^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * umip.c Emulation for instruction protected by the User-Mode Instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Prevention feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2017, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/umip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/traps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/insn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/insn-eval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #undef pr_fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define pr_fmt(fmt) "umip: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /** DOC: Emulation for User-Mode Instruction Prevention (UMIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * User-Mode Instruction Prevention is a security feature present in recent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * x86 processors that, when enabled, prevents a group of instructions (SGDT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * SIDT, SLDT, SMSW and STR) from being run in user mode by issuing a general
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * protection fault if the instruction is executed with CPL > 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Rather than relaying to the user space the general protection fault caused by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * the UMIP-protected instructions (in the form of a SIGSEGV signal), it can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * trapped and emulate the result of such instructions to provide dummy values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * This allows to both conserve the current kernel behavior and not reveal the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * system resources that UMIP intends to protect (i.e., the locations of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * global descriptor and interrupt descriptor tables, the segment selectors of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * the local descriptor table, the value of the task state register and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * contents of the CR0 register).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * This emulation is needed because certain applications (e.g., WineHQ and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * DOSEMU2) rely on this subset of instructions to function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * The instructions protected by UMIP can be split in two groups. Those which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * return a kernel memory address (SGDT and SIDT) and those which return a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * value (SLDT, STR and SMSW).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * For the instructions that return a kernel memory address, applications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * such as WineHQ rely on the result being located in the kernel memory space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * not the actual location of the table. The result is emulated as a hard-coded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * value that, lies close to the top of the kernel memory. The limit for the GDT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * and the IDT are set to zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * The instruction SMSW is emulated to return the value that the register CR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * has at boot time as set in the head_32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * SLDT and STR are emulated to return the values that the kernel programmatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * assigns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * - SLDT returns (GDT_ENTRY_LDT * 8) if an LDT has been set, 0 if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * - STR returns (GDT_ENTRY_TSS * 8).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Emulation is provided for both 32-bit and 64-bit processes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Care is taken to appropriately emulate the results when segmentation is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * used. That is, rather than relying on USER_DS and USER_CS, the function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * insn_get_addr_ref() inspects the segment descriptor pointed by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * registers in pt_regs. This ensures that we correctly obtain the segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * base address and the address and operand sizes even if the user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * application uses a local descriptor table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define UMIP_DUMMY_GDT_BASE 0xfffffffffffe0000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define UMIP_DUMMY_IDT_BASE 0xffffffffffff0000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * The SGDT and SIDT instructions store the contents of the global descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * table and interrupt table registers, respectively. The destination is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * memory operand of X+2 bytes. X bytes are used to store the base address of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * the table and 2 bytes are used to store the limit. In 32-bit processes X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * has a value of 4, in 64-bit processes X has a value of 8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define UMIP_GDT_IDT_BASE_SIZE_64BIT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define UMIP_GDT_IDT_BASE_SIZE_32BIT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define UMIP_GDT_IDT_LIMIT_SIZE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define UMIP_INST_SGDT 0 /* 0F 01 /0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define UMIP_INST_SIDT 1 /* 0F 01 /1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define UMIP_INST_SMSW 2 /* 0F 01 /4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define UMIP_INST_SLDT 3 /* 0F 00 /0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define UMIP_INST_STR 4 /* 0F 00 /1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static const char * const umip_insns[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) [UMIP_INST_SGDT] = "SGDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) [UMIP_INST_SIDT] = "SIDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) [UMIP_INST_SMSW] = "SMSW",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) [UMIP_INST_SLDT] = "SLDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) [UMIP_INST_STR] = "STR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define umip_pr_err(regs, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) umip_printk(regs, KERN_ERR, fmt, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define umip_pr_warn(regs, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) umip_printk(regs, KERN_WARNING, fmt, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * umip_printk() - Print a rate-limited message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @regs: Register set with the context in which the warning is printed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @log_level: Kernel log level to print the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @fmt: The text string to print
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * Print the text contained in @fmt. The print rate is limited to bursts of 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * messages every two minutes. The purpose of this customized version of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * printk() is to print messages when user space processes use any of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * UMIP-protected instructions. Thus, the printed text is prepended with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * task name and process ID number of the current task as well as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * instruction and stack pointers in @regs as seen when entering kernel mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static __printf(3, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void umip_printk(const struct pt_regs *regs, const char *log_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* Bursts of 5 messages every two minutes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static DEFINE_RATELIMIT_STATE(ratelimit, 2 * 60 * HZ, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct task_struct *tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (!__ratelimit(&ratelimit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) printk("%s" pr_fmt("%s[%d] ip:%lx sp:%lx: %pV"), log_level, tsk->comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) task_pid_nr(tsk), regs->ip, regs->sp, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * identify_insn() - Identify a UMIP-protected instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @insn: Instruction structure with opcode and ModRM byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * From the opcode and ModRM.reg in @insn identify, if any, a UMIP-protected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * instruction that can be emulated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * On success, a constant identifying a specific UMIP-protected instruction that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * can be emulated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * -EINVAL on error or when not an UMIP-protected instruction that can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * emulated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int identify_insn(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* By getting modrm we also get the opcode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) insn_get_modrm(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!insn->modrm.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* All the instructions of interest start with 0x0f. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (insn->opcode.bytes[0] != 0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (insn->opcode.bytes[1] == 0x1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) switch (X86_MODRM_REG(insn->modrm.value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return UMIP_INST_SGDT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return UMIP_INST_SIDT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return UMIP_INST_SMSW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) } else if (insn->opcode.bytes[1] == 0x0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (X86_MODRM_REG(insn->modrm.value) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return UMIP_INST_SLDT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) else if (X86_MODRM_REG(insn->modrm.value) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return UMIP_INST_STR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * emulate_umip_insn() - Emulate UMIP instructions and return dummy values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * @insn: Instruction structure with operands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * @umip_inst: A constant indicating the instruction to emulate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * @data: Buffer into which the dummy result is stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * @data_size: Size of the emulated result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * @x86_64: true if process is 64-bit, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * Emulate an instruction protected by UMIP and provide a dummy result. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * result of the emulation is saved in @data. The size of the results depends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * on both the instruction and type of operand (register vs memory address).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * The size of the result is updated in @data_size. Caller is responsible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * of providing a @data buffer of at least UMIP_GDT_IDT_BASE_SIZE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * UMIP_GDT_IDT_LIMIT_SIZE bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * 0 on success, -EINVAL on error while emulating.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int emulate_umip_insn(struct insn *insn, int umip_inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) unsigned char *data, int *data_size, bool x86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!data || !data_size || !insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * These two instructions return the base address and limit of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * global and interrupt descriptor table, respectively. According to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * Intel Software Development manual, the base address can be 24-bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * 32-bit or 64-bit. Limit is always 16-bit. If the operand size is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * 16-bit, the returned value of the base address is supposed to be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * zero-extended 24-byte number. However, it seems that a 32-byte number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * is always returned irrespective of the operand size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (umip_inst == UMIP_INST_SGDT || umip_inst == UMIP_INST_SIDT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) u64 dummy_base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u16 dummy_limit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* SGDT and SIDT do not use registers operands. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (X86_MODRM_MOD(insn->modrm.value) == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (umip_inst == UMIP_INST_SGDT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) dummy_base_addr = UMIP_DUMMY_GDT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) dummy_base_addr = UMIP_DUMMY_IDT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * 64-bit processes use the entire dummy base address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * 32-bit processes use the lower 32 bits of the base address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * dummy_base_addr is always 64 bits, but we memcpy the correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * number of bytes from it to the destination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (x86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *data_size = UMIP_GDT_IDT_BASE_SIZE_64BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) *data_size = UMIP_GDT_IDT_BASE_SIZE_32BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) memcpy(data + 2, &dummy_base_addr, *data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) *data_size += UMIP_GDT_IDT_LIMIT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) memcpy(data, &dummy_limit, UMIP_GDT_IDT_LIMIT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) } else if (umip_inst == UMIP_INST_SMSW || umip_inst == UMIP_INST_SLDT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) umip_inst == UMIP_INST_STR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) unsigned long dummy_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (umip_inst == UMIP_INST_SMSW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) dummy_value = CR0_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) } else if (umip_inst == UMIP_INST_STR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) dummy_value = GDT_ENTRY_TSS * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) } else if (umip_inst == UMIP_INST_SLDT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #ifdef CONFIG_MODIFY_LDT_SYSCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) down_read(¤t->mm->context.ldt_usr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (current->mm->context.ldt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) dummy_value = GDT_ENTRY_LDT * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dummy_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) up_read(¤t->mm->context.ldt_usr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) dummy_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * For these 3 instructions, the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * of bytes to be copied in the result buffer is determined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * by whether the operand is a register or a memory location.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * If operand is a register, return as many bytes as the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * size. If operand is memory, return only the two least
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * siginificant bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (X86_MODRM_MOD(insn->modrm.value) == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) *data_size = insn->opnd_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *data_size = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) memcpy(data, &dummy_value, *data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * force_sig_info_umip_fault() - Force a SIGSEGV with SEGV_MAPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * @addr: Address that caused the signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * @regs: Register set containing the instruction pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * Force a SIGSEGV signal with SEGV_MAPERR as the error code. This function is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * intended to be used to provide a segmentation fault when the result of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * UMIP emulation could not be copied to the user space memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * Returns: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static void force_sig_info_umip_fault(void __user *addr, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct task_struct *tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) tsk->thread.cr2 = (unsigned long)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) tsk->thread.error_code = X86_PF_USER | X86_PF_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) tsk->thread.trap_nr = X86_TRAP_PF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) force_sig_fault(SIGSEGV, SEGV_MAPERR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!(show_unhandled_signals && unhandled_signal(tsk, SIGSEGV)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) umip_pr_err(regs, "segfault in emulation. error%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) X86_PF_USER | X86_PF_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * fixup_umip_exception() - Fixup a general protection fault caused by UMIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * @regs: Registers as saved when entering the #GP handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * The instructions SGDT, SIDT, STR, SMSW and SLDT cause a general protection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * fault if executed with CPL > 0 (i.e., from user space). This function fixes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * the exception up and provides dummy results for SGDT, SIDT and SMSW; STR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * and SLDT are not fixed up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * If operands are memory addresses, results are copied to user-space memory as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * indicated by the instruction pointed by eIP using the registers indicated in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * the instruction operands. If operands are registers, results are copied into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * the context that was saved when entering kernel mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * True if emulation was successful; false if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) bool fixup_umip_exception(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int nr_copied, reg_offset, dummy_data_size, umip_inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* 10 bytes is the maximum size of the result of UMIP instructions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) unsigned char dummy_data[10] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) unsigned char buf[MAX_INSN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned long *reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) void __user *uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct insn insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (!regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) nr_copied = insn_fetch_from_user(regs, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * The insn_fetch_from_user above could have failed if user code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * is protected by a memory protection key. Give up on emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * in such a case. Should we issue a page fault?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (!nr_copied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (!insn_decode(&insn, regs, buf, nr_copied))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) umip_inst = identify_insn(&insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (umip_inst < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) umip_pr_warn(regs, "%s instruction cannot be used by applications.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) umip_insns[umip_inst]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) umip_pr_warn(regs, "For now, expensive software emulation returns the result.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (emulate_umip_insn(&insn, umip_inst, dummy_data, &dummy_data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) user_64bit_mode(regs)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * If operand is a register, write result to the copy of the register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * value that was pushed to the stack when entering into kernel mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * Upon exit, the value we write will be restored to the actual hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (X86_MODRM_MOD(insn.modrm.value) == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) reg_offset = insn_get_modrm_rm_off(&insn, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * Negative values are usually errors. In memory addressing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * the exception is -EDOM. Since we expect a register operand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * all negative values are errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (reg_offset < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) reg_addr = (unsigned long *)((unsigned long)regs + reg_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) memcpy(reg_addr, dummy_data, dummy_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) uaddr = insn_get_addr_ref(&insn, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if ((unsigned long)uaddr == -1L)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) nr_copied = copy_to_user(uaddr, dummy_data, dummy_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (nr_copied > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * If copy fails, send a signal and tell caller that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * fault was fixed up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) force_sig_info_umip_fault(uaddr, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* increase IP to let the program keep going */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) regs->ip += insn.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }