Lines Matching +full:two +full:- +full:user

2  * umip.c Emulation for instruction protected by the User-Mode Instruction
6 * Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
13 #include <asm/insn-eval.h>
19 /** DOC: Emulation for User-Mode Instruction Prevention (UMIP)
21 * User-Mode Instruction Prevention is a security feature present in recent
23 * SIDT, SLDT, SMSW and STR) from being run in user mode by issuing a general
26 * Rather than relaying to the user space the general protection fault caused by
27 * the UMIP-protected instructions (in the form of a SIGSEGV signal), it can be
38 * The instructions protected by UMIP can be split in two groups. Those which
44 * not the actual location of the table. The result is emulated as a hard-coded
52 * - SLDT returns (GDT_ENTRY_LDT * 8) if an LDT has been set, 0 if not.
53 * - STR returns (GDT_ENTRY_TSS * 8).
55 * Emulation is provided for both 32-bit and 64-bit processes.
61 * base address and the address and operand sizes even if the user space
72 * the table and 2 bytes are used to store the limit. In 32-bit processes X
73 * has a value of 4, in 64-bit processes X has a value of 8.
99 * umip_printk() - Print a rate-limited message
105 * messages every two minutes. The purpose of this customized version of
106 * printk() is to print messages when user space processes use any of the
107 * UMIP-protected instructions. Thus, the printed text is prepended with the
119 /* Bursts of 5 messages every two minutes */ in umip_printk()
131 printk("%s" pr_fmt("%s[%d] ip:%lx sp:%lx: %pV"), log_level, tsk->comm, in umip_printk()
132 task_pid_nr(tsk), regs->ip, regs->sp, &vaf); in umip_printk()
137 * identify_insn() - Identify a UMIP-protected instruction
140 * From the opcode and ModRM.reg in @insn identify, if any, a UMIP-protected
145 * On success, a constant identifying a specific UMIP-protected instruction that
148 * -EINVAL on error or when not an UMIP-protected instruction that can be
156 if (!insn->modrm.nbytes) in identify_insn()
157 return -EINVAL; in identify_insn()
160 if (insn->opcode.bytes[0] != 0xf) in identify_insn()
161 return -EINVAL; in identify_insn()
163 if (insn->opcode.bytes[1] == 0x1) { in identify_insn()
164 switch (X86_MODRM_REG(insn->modrm.value)) { in identify_insn()
172 return -EINVAL; in identify_insn()
174 } else if (insn->opcode.bytes[1] == 0x0) { in identify_insn()
175 if (X86_MODRM_REG(insn->modrm.value) == 0) in identify_insn()
177 else if (X86_MODRM_REG(insn->modrm.value) == 1) in identify_insn()
180 return -EINVAL; in identify_insn()
182 return -EINVAL; in identify_insn()
187 * emulate_umip_insn() - Emulate UMIP instructions and return dummy values
192 * @x86_64: true if process is 64-bit, false otherwise
203 * 0 on success, -EINVAL on error while emulating.
209 return -EINVAL; in emulate_umip_insn()
211 * These two instructions return the base address and limit of the in emulate_umip_insn()
213 * Intel Software Development manual, the base address can be 24-bit, in emulate_umip_insn()
214 * 32-bit or 64-bit. Limit is always 16-bit. If the operand size is in emulate_umip_insn()
215 * 16-bit, the returned value of the base address is supposed to be a in emulate_umip_insn()
216 * zero-extended 24-byte number. However, it seems that a 32-byte number in emulate_umip_insn()
224 if (X86_MODRM_MOD(insn->modrm.value) == 3) in emulate_umip_insn()
225 return -EINVAL; in emulate_umip_insn()
233 * 64-bit processes use the entire dummy base address. in emulate_umip_insn()
234 * 32-bit processes use the lower 32 bits of the base address. in emulate_umip_insn()
258 down_read(&current->mm->context.ldt_usr_sem); in emulate_umip_insn()
259 if (current->mm->context.ldt) in emulate_umip_insn()
263 up_read(&current->mm->context.ldt_usr_sem); in emulate_umip_insn()
274 * size. If operand is memory, return only the two least in emulate_umip_insn()
277 if (X86_MODRM_MOD(insn->modrm.value) == 3) in emulate_umip_insn()
278 *data_size = insn->opnd_bytes; in emulate_umip_insn()
284 return -EINVAL; in emulate_umip_insn()
291 * force_sig_info_umip_fault() - Force a SIGSEGV with SEGV_MAPERR
297 * UMIP emulation could not be copied to the user space memory.
305 tsk->thread.cr2 = (unsigned long)addr; in force_sig_info_umip_fault()
306 tsk->thread.error_code = X86_PF_USER | X86_PF_WRITE; in force_sig_info_umip_fault()
307 tsk->thread.trap_nr = X86_TRAP_PF; in force_sig_info_umip_fault()
319 * fixup_umip_exception() - Fixup a general protection fault caused by UMIP
323 * fault if executed with CPL > 0 (i.e., from user space). This function fixes
327 * If operands are memory addresses, results are copied to user-space memory as
352 * The insn_fetch_from_user above could have failed if user code in fixup_umip_exception()
386 * the exception is -EDOM. Since we expect a register operand, in fixup_umip_exception()
396 if ((unsigned long)uaddr == -1L) in fixup_umip_exception()
411 regs->ip += insn.length; in fixup_umip_exception()