Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/amd64/amd64 Inline _FRAME_GREG, and mask only 16 bi...



details:   https://anonhg.NetBSD.org/src/rev/14b9746e0e0c
branches:  trunk
changeset: 828084:14b9746e0e0c
user:      maxv <maxv%NetBSD.org@localhost>
date:      Mon Nov 27 09:18:01 2017 +0000

description:
Inline _FRAME_GREG, and mask only 16 bits of the segment registers,
otherwise the upper 48 bits may contain stack garbage. By the way, I find
it suspicious that we're not masking regs[_REG_RFLAGS] with PSL_USER in
process_write_regs.

diffstat:

 sys/arch/amd64/amd64/machdep.c         |  83 +++++++++++++++++++++++----------
 sys/arch/amd64/amd64/process_machdep.c |  75 +++++++++++++++++++++++-------
 2 files changed, 115 insertions(+), 43 deletions(-)

diffs (241 lines):

diff -r aa56a76a0c08 -r 14b9746e0e0c sys/arch/amd64/amd64/machdep.c
--- a/sys/arch/amd64/amd64/machdep.c    Mon Nov 27 09:10:12 2017 +0000
+++ b/sys/arch/amd64/amd64/machdep.c    Mon Nov 27 09:18:01 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.277 2017/11/21 10:42:44 maxv Exp $       */
+/*     $NetBSD: machdep.c,v 1.278 2017/11/27 09:18:01 maxv Exp $       */
 
 /*
  * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -110,7 +110,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.277 2017/11/21 10:42:44 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.278 2017/11/27 09:18:01 maxv Exp $");
 
 /* #define XENDEBUG_LOW  */
 
@@ -1876,10 +1876,33 @@
        const struct trapframe *tf = l->l_md.md_regs;
        __greg_t ras_rip;
 
-       /* Copy general registers member by member */
-#define copy_from_tf(reg, REG, idx) mcp->__gregs[_REG_##REG] = tf->tf_##reg;
-       _FRAME_GREG(copy_from_tf)
-#undef copy_from_tf
+       mcp->__gregs[_REG_RDI] = tf->tf_rdi;
+       mcp->__gregs[_REG_RSI] = tf->tf_rsi;
+       mcp->__gregs[_REG_RDX] = tf->tf_rdx;
+       mcp->__gregs[_REG_R10] = tf->tf_r10;
+       mcp->__gregs[_REG_R8]  = tf->tf_r8;
+       mcp->__gregs[_REG_R9]  = tf->tf_r9;
+       /* argX not touched */
+       mcp->__gregs[_REG_RCX] = tf->tf_rcx;
+       mcp->__gregs[_REG_R11] = tf->tf_r11;
+       mcp->__gregs[_REG_R12] = tf->tf_r12;
+       mcp->__gregs[_REG_R13] = tf->tf_r13;
+       mcp->__gregs[_REG_R14] = tf->tf_r14;
+       mcp->__gregs[_REG_R15] = tf->tf_r15;
+       mcp->__gregs[_REG_RBP] = tf->tf_rbp;
+       mcp->__gregs[_REG_RBX] = tf->tf_rbx;
+       mcp->__gregs[_REG_RAX] = tf->tf_rax;
+       mcp->__gregs[_REG_GS]  = tf->tf_gs & 0xFFFF;
+       mcp->__gregs[_REG_FS]  = tf->tf_fs & 0xFFFF;
+       mcp->__gregs[_REG_ES]  = tf->tf_es & 0xFFFF;
+       mcp->__gregs[_REG_DS]  = tf->tf_ds & 0xFFFF;
+       mcp->__gregs[_REG_TRAPNO] = tf->tf_trapno;
+       mcp->__gregs[_REG_ERR] = tf->tf_err;
+       mcp->__gregs[_REG_RIP] = tf->tf_rip;
+       mcp->__gregs[_REG_CS]  = tf->tf_cs & 0xFFFF;
+       mcp->__gregs[_REG_RFLAGS] = tf->tf_rflags;
+       mcp->__gregs[_REG_RSP] = tf->tf_rsp;
+       mcp->__gregs[_REG_SS]  = tf->tf_ss & 0xFFFF;
 
        if ((ras_rip = (__greg_t)ras_lookup(l->l_proc,
            (void *) mcp->__gregs[_REG_RIP])) != -1)
@@ -1901,7 +1924,6 @@
        const __greg_t *gr = mcp->__gregs;
        struct proc *p = l->l_proc;
        int error;
-       int err, trapno;
        int64_t rflags;
 
        CTASSERT(sizeof (mcontext_t) == 26 * 8 + 8 + 512);
@@ -1910,33 +1932,44 @@
                error = cpu_mcontext_validate(l, mcp);
                if (error != 0)
                        return error;
-               /*
-                * save and restore some values we don't want to change.
-                * _FRAME_GREG(copy_to_tf) below overwrites them.
-                *
-                * XXX maybe inline this.
-                */
+
+               tf->tf_rdi  = gr[_REG_RDI];
+               tf->tf_rsi  = gr[_REG_RSI];
+               tf->tf_rdx  = gr[_REG_RDX];
+               tf->tf_r10  = gr[_REG_R10];
+               tf->tf_r8   = gr[_REG_R8];
+               tf->tf_r9   = gr[_REG_R9];
+               /* argX not touched */
+               tf->tf_rcx  = gr[_REG_RCX];
+               tf->tf_r11  = gr[_REG_R11];
+               tf->tf_r12  = gr[_REG_R12];
+               tf->tf_r13  = gr[_REG_R13];
+               tf->tf_r14  = gr[_REG_R14];
+               tf->tf_r15  = gr[_REG_R15];
+               tf->tf_rbp  = gr[_REG_RBP];
+               tf->tf_rbx  = gr[_REG_RBX];
+               tf->tf_rax  = gr[_REG_RAX];
+               tf->tf_gs   = gr[_REG_GS] & 0xFFFF;
+               tf->tf_fs   = gr[_REG_FS] & 0xFFFF;
+               tf->tf_es   = gr[_REG_ES] & 0xFFFF;
+               tf->tf_ds   = gr[_REG_DS] & 0xFFFF;
+               /* trapno, err not touched */
+               tf->tf_rip  = gr[_REG_RIP];
+               tf->tf_cs   = gr[_REG_CS] & 0xFFFF;
                rflags = tf->tf_rflags;
-               err = tf->tf_err;
-               trapno = tf->tf_trapno;
-
-               /* Copy general registers member by member */
-#define copy_to_tf(reg, REG, idx) tf->tf_##reg = gr[_REG_##REG];
-               _FRAME_GREG(copy_to_tf)
-#undef copy_to_tf
+               rflags &= ~PSL_USER;
+               tf->tf_rflags = rflags | (gr[_REG_RFLAGS] & PSL_USER);
+               tf->tf_rsp  = gr[_REG_RSP];
+               tf->tf_ss   = gr[_REG_SS] & 0xFFFF;
 
 #ifdef XEN
                /*
                 * Xen has its own way of dealing with %cs and %ss,
-                * reset it to proper values.
+                * reset them to proper values.
                 */
                tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
                tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
 #endif
-               rflags &= ~PSL_USER;
-               tf->tf_rflags = rflags | (gr[_REG_RFLAGS] & PSL_USER);
-               tf->tf_err = err;
-               tf->tf_trapno = trapno;
 
                l->l_md.md_flags |= MDL_IRET;
        }
diff -r aa56a76a0c08 -r 14b9746e0e0c sys/arch/amd64/amd64/process_machdep.c
--- a/sys/arch/amd64/amd64/process_machdep.c    Mon Nov 27 09:10:12 2017 +0000
+++ b/sys/arch/amd64/amd64/process_machdep.c    Mon Nov 27 09:18:01 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: process_machdep.c,v 1.36 2017/10/19 09:32:01 maxv Exp $        */
+/*     $NetBSD: process_machdep.c,v 1.37 2017/11/27 09:18:01 maxv Exp $        */
 
 /*
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.36 2017/10/19 09:32:01 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.37 2017/11/27 09:18:01 maxv Exp $");
 
 #include "opt_xen.h"
 #include <sys/param.h>
@@ -109,9 +109,33 @@
                return EINVAL;
        }
 
-#define copy_to_reg(reg, REG, idx) regs->regs[_REG_##REG] = tf->tf_##reg;
-       _FRAME_GREG(copy_to_reg)
-#undef copy_to_reg
+       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;
+       /* 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]  = tf->tf_gs & 0xFFFF;
+       regs->regs[_REG_FS]  = tf->tf_fs & 0xFFFF;
+       regs->regs[_REG_ES]  = tf->tf_es & 0xFFFF;
+       regs->regs[_REG_DS]  = tf->tf_ds & 0xFFFF;
+       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]  = tf->tf_cs & 0xFFFF;
+       regs->regs[_REG_RFLAGS] = tf->tf_rflags;
+       regs->regs[_REG_RSP] = tf->tf_rsp;
+       regs->regs[_REG_SS]  = tf->tf_ss & 0xFFFF;
 
        return 0;
 }
@@ -151,30 +175,45 @@
        struct proc *p = l->l_proc;
        int error;
        const long *regs = regp->regs;
-       int err, trapno;
 
        if (p->p_flag & PK_32) {
                return EINVAL;
        }
 
        /*
-        * Check for security violations.
-        * Note that struct regs is compatible with
-        * the __gregs array in mcontext_t.
+        * Check for security violations. Note that struct regs is compatible
+        * with the __gregs array in mcontext_t.
         */
        error = cpu_mcontext_validate(l, (const mcontext_t *)regs);
        if (error != 0)
                return error;
 
-       err = tf->tf_err;
-       trapno = tf->tf_trapno;
-
-#define copy_to_frame(reg, REG, idx) tf->tf_##reg = regs[_REG_##REG];
-       _FRAME_GREG(copy_to_frame)
-#undef copy_to_frame
-
-       tf->tf_err = err;
-       tf->tf_trapno = trapno;
+       tf->tf_rdi  = regs[_REG_RDI];
+       tf->tf_rsi  = regs[_REG_RSI];
+       tf->tf_rdx  = regs[_REG_RDX];
+       tf->tf_r10  = regs[_REG_R10];
+       tf->tf_r8   = regs[_REG_R8];
+       tf->tf_r9   = regs[_REG_R9];
+       /* argX not touched */
+       tf->tf_rcx  = regs[_REG_RCX];
+       tf->tf_r11  = regs[_REG_R11];
+       tf->tf_r12  = regs[_REG_R12];
+       tf->tf_r13  = regs[_REG_R13];
+       tf->tf_r14  = regs[_REG_R14];
+       tf->tf_r15  = regs[_REG_R15];
+       tf->tf_rbp  = regs[_REG_RBP];
+       tf->tf_rbx  = regs[_REG_RBX];
+       tf->tf_rax  = regs[_REG_RAX];
+       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;
+       /* trapno, err not touched */
+       tf->tf_rip  = regs[_REG_RIP];
+       tf->tf_cs   = regs[_REG_CS] & 0xFFFF;
+       tf->tf_rflags = regs[_REG_RFLAGS];
+       tf->tf_rsp  = regs[_REG_RSP];
+       tf->tf_ss   = regs[_REG_SS] & 0xFFFF;
 
 #ifdef XEN
        /* see comment in cpu_setmcontext */



Home | Main Index | Thread Index | Old Index