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