Module Name:    src
Committed By:   maxv
Date:           Mon Nov 27 09:18:01 UTC 2017

Modified Files:
        src/sys/arch/amd64/amd64: machdep.c process_machdep.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.277 -r1.278 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.36 -r1.37 src/sys/arch/amd64/amd64/process_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.277 src/sys/arch/amd64/amd64/machdep.c:1.278
--- src/sys/arch/amd64/amd64/machdep.c:1.277	Tue Nov 21 10:42:44 2017
+++ src/sys/arch/amd64/amd64/machdep.c	Mon Nov 27 09:18:01 2017
@@ -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 @@ cpu_getmcontext(struct lwp *l, mcontext_
 	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 @@ cpu_setmcontext(struct lwp *l, const mco
 	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 @@ cpu_setmcontext(struct lwp *l, const mco
 		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.
-		 */
-		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
+		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;
+		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;
 	}

Index: src/sys/arch/amd64/amd64/process_machdep.c
diff -u src/sys/arch/amd64/amd64/process_machdep.c:1.36 src/sys/arch/amd64/amd64/process_machdep.c:1.37
--- src/sys/arch/amd64/amd64/process_machdep.c:1.36	Thu Oct 19 09:32:01 2017
+++ src/sys/arch/amd64/amd64/process_machdep.c	Mon Nov 27 09:18:01 2017
@@ -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 @@ process_read_regs(struct lwp *l, struct 
 		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 @@ process_write_regs(struct lwp *l, const 
 	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 */

Reply via email to