? o Index: machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/amd64/amd64/machdep.c,v retrieving revision 1.332 diff -u -p -u -r1.332 machdep.c --- machdep.c 12 Jun 2019 14:28:38 -0000 1.332 +++ machdep.c 23 Jun 2019 03:40:54 -0000 @@ -2095,40 +2095,46 @@ cpu_setmcontext(struct lwp *l, const mco int cpu_mcontext_validate(struct lwp *l, const mcontext_t *mcp) { - struct proc *p __diagused = l->l_proc; + struct proc *p = l->l_proc; struct trapframe *tf = l->l_md.md_regs; const __greg_t *gr; uint16_t sel; + const bool pk32 = (p->p_flag & PK_32) != 0; - KASSERT((p->p_flag & PK_32) == 0); gr = mcp->__gregs; if (((gr[_REG_RFLAGS] ^ tf->tf_rflags) & PSL_USERSTATIC) != 0) return EINVAL; +#define VUD(sel) (pk32 ? VALID_USER_DSEL32(sel) : VALID_USER_DSEL(sel)) +#define VUF(sel) (pk32 ? (VALID_USER_DSEL32(sel) || VALID_USER_FSEL32(sel)) \ + : VALID_USER_DSEL(sel)) +#define VUG(sel) (pk32 ? (VALID_USER_DSEL32(sel) || VALID_USER_GSEL32(sel)) \ + : VALID_USER_DSEL(sel)) +#define VUC(sel) (pk32 ? VALID_USER_CSEL32(sel) : VALID_USER_CSEL(sel)) sel = gr[_REG_ES] & 0xffff; - if (sel != 0 && !VALID_USER_DSEL(sel)) + if (sel != 0 && !VUD(sel)) return EINVAL; sel = gr[_REG_FS] & 0xffff; - if (sel != 0 && !VALID_USER_DSEL(sel)) + if (sel != 0 && !VUF(sel)) return EINVAL; sel = gr[_REG_GS] & 0xffff; - if (sel != 0 && !VALID_USER_DSEL(sel)) + if (sel != 0 && !VUG(sel)) return EINVAL; sel = gr[_REG_DS] & 0xffff; - if (!VALID_USER_DSEL(sel)) + if (!VUD(sel)) return EINVAL; #ifndef XENPV sel = gr[_REG_SS] & 0xffff; - if (!VALID_USER_DSEL(sel)) + if (!VUD(sel)) return EINVAL; sel = gr[_REG_CS] & 0xffff; - if (!VALID_USER_CSEL(sel)) + if (!VUC(sel)) return EINVAL; #endif Index: process_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/amd64/amd64/process_machdep.c,v retrieving revision 1.39 diff -u -p -u -r1.39 process_machdep.c --- process_machdep.c 11 Feb 2019 14:59:32 -0000 1.39 +++ process_machdep.c 23 Jun 2019 03:40:54 -0000 @@ -100,42 +100,48 @@ process_frame(struct lwp *l) } int -process_read_regs(struct lwp *l, struct reg *regs) +process_read_regs(struct lwp *l, struct reg *regp) { struct trapframe *tf = process_frame(l); - struct proc *p = l->l_proc; + long *regs = regp->regs; + const bool pk32 = (l->l_proc->p_flag & PK_32) != 0; - if (p->p_flag & PK_32) { - return EINVAL; - } - - regs->regs[_REG_RDI] = tf->tf_rdi; - regs->regs[_REG_RSI] = tf->tf_rsi; - regs->regs[_REG_RDX] = tf->tf_rdx; - regs->regs[_REG_R10] = tf->tf_r10; - regs->regs[_REG_R8] = tf->tf_r8; - regs->regs[_REG_R9] = tf->tf_r9; + regs[_REG_RDI] = tf->tf_rdi; + regs[_REG_RSI] = tf->tf_rsi; + regs[_REG_RDX] = tf->tf_rdx; + regs[_REG_R10] = tf->tf_r10; + regs[_REG_R8] = tf->tf_r8; + regs[_REG_R9] = tf->tf_r9; /* argX not touched */ - regs->regs[_REG_RCX] = tf->tf_rcx; - regs->regs[_REG_R11] = tf->tf_r11; - regs->regs[_REG_R12] = tf->tf_r12; - regs->regs[_REG_R13] = tf->tf_r13; - regs->regs[_REG_R14] = tf->tf_r14; - regs->regs[_REG_R15] = tf->tf_r15; - regs->regs[_REG_RBP] = tf->tf_rbp; - regs->regs[_REG_RBX] = tf->tf_rbx; - regs->regs[_REG_RAX] = tf->tf_rax; - regs->regs[_REG_GS] = 0; - regs->regs[_REG_FS] = 0; - regs->regs[_REG_ES] = GSEL(GUDATA_SEL, SEL_UPL); - regs->regs[_REG_DS] = GSEL(GUDATA_SEL, SEL_UPL); - regs->regs[_REG_TRAPNO] = tf->tf_trapno; - regs->regs[_REG_ERR] = tf->tf_err; - regs->regs[_REG_RIP] = tf->tf_rip; - regs->regs[_REG_CS] = LSEL(LUCODE_SEL, SEL_UPL); - regs->regs[_REG_RFLAGS] = tf->tf_rflags; - regs->regs[_REG_RSP] = tf->tf_rsp; - regs->regs[_REG_SS] = LSEL(LUDATA_SEL, SEL_UPL); + regs[_REG_RCX] = tf->tf_rcx; + regs[_REG_R11] = tf->tf_r11; + regs[_REG_R12] = tf->tf_r12; + regs[_REG_R13] = tf->tf_r13; + regs[_REG_R14] = tf->tf_r14; + regs[_REG_R15] = tf->tf_r15; + regs[_REG_RBP] = tf->tf_rbp; + regs[_REG_RBX] = tf->tf_rbx; + regs[_REG_RAX] = tf->tf_rax; + if (pk32) { + regs[_REG_GS] = tf->tf_gs & 0xffff; + regs[_REG_FS] = tf->tf_fs & 0xffff; + regs[_REG_ES] = tf->tf_es & 0xffff; + regs[_REG_DS] = tf->tf_ds & 0xffff; + regs[_REG_CS] = tf->tf_cs & 0xffff; + regs[_REG_SS] = tf->tf_ss & 0xffff; + } else { + regs[_REG_GS] = 0; + regs[_REG_FS] = 0; + regs[_REG_ES] = GSEL(GUDATA_SEL, SEL_UPL); + regs[_REG_DS] = GSEL(GUDATA_SEL, SEL_UPL); + regs[_REG_CS] = LSEL(LUCODE_SEL, SEL_UPL); + regs[_REG_SS] = LSEL(LUDATA_SEL, SEL_UPL); + } + regs[_REG_TRAPNO] = tf->tf_trapno; + regs[_REG_ERR] = tf->tf_err; + regs[_REG_RIP] = tf->tf_rip; + regs[_REG_RFLAGS] = tf->tf_rflags; + regs[_REG_RSP] = tf->tf_rsp; return 0; } @@ -143,11 +149,6 @@ process_read_regs(struct lwp *l, struct int process_read_fpregs(struct lwp *l, struct fpreg *regs, size_t *sz) { - struct proc *p = l->l_proc; - - if (p->p_flag & PK_32) { - return EINVAL; - } process_read_fpregs_xmm(l, ®s->fxstate); @@ -157,11 +158,6 @@ process_read_fpregs(struct lwp *l, struc int process_read_dbregs(struct lwp *l, struct dbreg *regs, size_t *sz) { - struct proc *p = l->l_proc; - - if (p->p_flag & PK_32) { - return EINVAL; - } x86_dbregs_read(l, regs); @@ -172,13 +168,9 @@ int process_write_regs(struct lwp *l, const struct reg *regp) { struct trapframe *tf = process_frame(l); - struct proc *p = l->l_proc; int error; const long *regs = regp->regs; - - if (p->p_flag & PK_32) { - return EINVAL; - } + const bool pk32 = (l->l_proc->p_flag & PK_32) != 0; /* * Check for security violations. Note that struct regs is compatible @@ -204,16 +196,25 @@ process_write_regs(struct lwp *l, const tf->tf_rbp = regs[_REG_RBP]; tf->tf_rbx = regs[_REG_RBX]; tf->tf_rax = regs[_REG_RAX]; - tf->tf_gs = 0; - tf->tf_fs = 0; - tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL); - tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL); + if (pk32) { + tf->tf_gs = regs[_REG_GS] & 0xffff; + tf->tf_fs = regs[_REG_FS] & 0xffff; + tf->tf_es = regs[_REG_ES] & 0xffff; + tf->tf_ds = regs[_REG_DS] & 0xffff; + tf->tf_cs = regs[_REG_CS] & 0xffff; + tf->tf_ss = regs[_REG_SS] & 0xffff; + } else { + tf->tf_gs = 0; + tf->tf_fs = 0; + tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL); + tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL); + tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL); + tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL); + } /* trapno, err not touched */ tf->tf_rip = regs[_REG_RIP]; - tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL); tf->tf_rflags = regs[_REG_RFLAGS]; tf->tf_rsp = regs[_REG_RSP]; - tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL); #ifdef XENPV /* see comment in cpu_setmcontext */ @@ -227,11 +228,6 @@ process_write_regs(struct lwp *l, const int process_write_fpregs(struct lwp *l, const struct fpreg *regs, size_t sz) { - struct proc *p = l->l_proc; - - if (p->p_flag & PK_32) { - return EINVAL; - } process_write_fpregs_xmm(l, ®s->fxstate); return 0; @@ -240,13 +236,8 @@ process_write_fpregs(struct lwp *l, cons int process_write_dbregs(struct lwp *l, const struct dbreg *regs, size_t sz) { - struct proc *p = l->l_proc; int error; - if (p->p_flag & PK_32) { - return EINVAL; - } - /* * Check for security violations. */ @@ -276,11 +267,6 @@ int process_set_pc(struct lwp *l, void *addr) { struct trapframe *tf = process_frame(l); - struct proc *p = l->l_proc; - - if (p->p_flag & PK_32) { - return EINVAL; - } if ((uint64_t)addr >= VM_MAXUSER_ADDRESS) return EINVAL;