Module Name:    src
Committed By:   maxv
Date:           Thu Oct 19 10:01:10 UTC 2017

Modified Files:
        src/sys/arch/amd64/amd64: machdep.c netbsd32_machdep.c
        src/sys/compat/linux/arch/amd64: linux_machdep.c
        src/sys/compat/linux32/arch/amd64: linux32_machdep.c

Log Message:
Always mask the 16 bits of the segregs in the trapframe. We don't zero-
extend the uint64_t's when building it, so we're leaking 48 bits of kernel
stack to userland.

Having said that, it appears that I unintentionally fixed most of this
issue in locore.S::rev1.127 - by building the frame with interrupts
disabled, we are implicitly guaranteeing that the structure doesn't get
overwritten by the kernel. Which means, we are leaking to userland data
that comes from userland anyway.

(still other places with this issue, but I'll fix them differently)


To generate a diff of this commit:
cvs rdiff -u -r1.268 -r1.269 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.111 -r1.112 src/sys/arch/amd64/amd64/netbsd32_machdep.c
cvs rdiff -u -r1.53 -r1.54 src/sys/compat/linux/arch/amd64/linux_machdep.c
cvs rdiff -u -r1.41 -r1.42 \
    src/sys/compat/linux32/arch/amd64/linux32_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.268 src/sys/arch/amd64/amd64/machdep.c:1.269
--- src/sys/arch/amd64/amd64/machdep.c:1.268	Tue Oct 17 07:48:10 2017
+++ src/sys/arch/amd64/amd64/machdep.c	Thu Oct 19 10:01:09 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.268 2017/10/17 07:48:10 maxv Exp $	*/
+/*	$NetBSD: machdep.c,v 1.269 2017/10/19 10:01:09 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.268 2017/10/17 07:48:10 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.269 2017/10/19 10:01:09 maxv Exp $");
 
 /* #define XENDEBUG_LOW  */
 
@@ -2123,6 +2123,8 @@ cpu_fsgs_reload(struct lwp *l, int fssel
 	KASSERT(l == curlwp);
 
 	tf = l->l_md.md_regs;
+	fssel &= 0xFFFF;
+	gssel &= 0xFFFF;
 
 	pcb = lwp_getpcb(l);
 	kpreempt_disable();

Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c
diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.111 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.112
--- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.111	Sun Oct 15 12:49:53 2017
+++ src/sys/arch/amd64/amd64/netbsd32_machdep.c	Thu Oct 19 10:01:09 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_machdep.c,v 1.111 2017/10/15 12:49:53 maxv Exp $	*/
+/*	$NetBSD: netbsd32_machdep.c,v 1.112 2017/10/19 10:01:09 maxv Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.111 2017/10/15 12:49:53 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.112 2017/10/19 10:01:09 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -208,10 +208,10 @@ netbsd32_sendsig_sigcontext(const ksigin
 	frame.sf_code = ksi->ksi_trap;
 	frame.sf_scp = (uint32_t)(u_long)&fp->sf_sc;
 
-	frame.sf_sc.sc_ds = tf->tf_ds;
-	frame.sf_sc.sc_es = tf->tf_es;
-	frame.sf_sc.sc_fs = tf->tf_fs;
-	frame.sf_sc.sc_gs = tf->tf_gs;
+	frame.sf_sc.sc_ds = tf->tf_ds & 0xFFFF;
+	frame.sf_sc.sc_es = tf->tf_es & 0xFFFF;
+	frame.sf_sc.sc_fs = tf->tf_fs & 0xFFFF;
+	frame.sf_sc.sc_gs = tf->tf_gs & 0xFFFF;
 
 	frame.sf_sc.sc_eflags = tf->tf_rflags;
 	frame.sf_sc.sc_edi = tf->tf_rdi;
@@ -222,9 +222,9 @@ netbsd32_sendsig_sigcontext(const ksigin
 	frame.sf_sc.sc_ecx = tf->tf_rcx;
 	frame.sf_sc.sc_eax = tf->tf_rax;
 	frame.sf_sc.sc_eip = tf->tf_rip;
-	frame.sf_sc.sc_cs = tf->tf_cs;
+	frame.sf_sc.sc_cs = tf->tf_cs & 0xFFFF;
 	frame.sf_sc.sc_esp = tf->tf_rsp;
-	frame.sf_sc.sc_ss = tf->tf_ss;
+	frame.sf_sc.sc_ss = tf->tf_ss & 0xFFFF;
 	frame.sf_sc.sc_trapno = tf->tf_trapno;
 	frame.sf_sc.sc_err = tf->tf_err;
 
@@ -417,8 +417,8 @@ compat_16_netbsd32___sigreturn14(struct 
 
 	/* Restore register context. */
 	tf = l->l_md.md_regs;
-	tf->tf_ds = context.sc_ds;
-	tf->tf_es = context.sc_es;
+	tf->tf_ds = context.sc_ds & 0xFFFF;
+	tf->tf_es = context.sc_es & 0xFFFF;
 	cpu_fsgs_reload(l, context.sc_fs, context.sc_gs);
 	tf->tf_rflags = context.sc_eflags;
 	tf->tf_rdi = context.sc_edi;
@@ -430,9 +430,9 @@ compat_16_netbsd32___sigreturn14(struct 
 	tf->tf_rax = context.sc_eax;
 
 	tf->tf_rip = context.sc_eip;
-	tf->tf_cs = context.sc_cs;
+	tf->tf_cs = context.sc_cs & 0xFFFF;
 	tf->tf_rsp = context.sc_esp;
-	tf->tf_ss = context.sc_ss;
+	tf->tf_ss = context.sc_ss & 0xFFFF;
 
 	mutex_enter(p->p_lock);
 	/* Restore signal stack. */
@@ -595,12 +595,12 @@ netbsd32_process_write_regs(struct lwp *
 	tf->tf_rdi = regs->r_edi;
 	tf->tf_rip = regs->r_eip;
 	tf->tf_rflags = regs->r_eflags;
-	tf->tf_cs = regs->r_cs;
-	tf->tf_ss = regs->r_ss;
-	tf->tf_ds = regs->r_ds;
-	tf->tf_es = regs->r_es;
-	tf->tf_fs = regs->r_fs;
-	tf->tf_gs = regs->r_gs;
+	tf->tf_cs = regs->r_cs & 0xFFFF;
+	tf->tf_ss = regs->r_ss & 0xFFFF;
+	tf->tf_ds = regs->r_ds & 0xFFFF;
+	tf->tf_es = regs->r_es & 0xFFFF;
+	tf->tf_fs = regs->r_fs & 0xFFFF;
+	tf->tf_gs = regs->r_gs & 0xFFFF;
 
 	return 0;
 }
@@ -943,8 +943,8 @@ cpu_setmcontext32(struct lwp *l, const m
 			return error;
 
 		cpu_fsgs_reload(l, gr[_REG32_FS], gr[_REG32_GS]);
-		tf->tf_es = gr[_REG32_ES];
-		tf->tf_ds = gr[_REG32_DS];
+		tf->tf_es = gr[_REG32_ES] & 0xFFFF;
+		tf->tf_ds = gr[_REG32_DS] & 0xFFFF;
 		/* Only change the user-alterable part of eflags */
 		tf->tf_rflags &= ~PSL_USER;
 		tf->tf_rflags |= (gr[_REG32_EFL] & PSL_USER);
@@ -956,9 +956,9 @@ cpu_setmcontext32(struct lwp *l, const m
 		tf->tf_rcx    = gr[_REG32_ECX];
 		tf->tf_rax    = gr[_REG32_EAX];
 		tf->tf_rip    = gr[_REG32_EIP];
-		tf->tf_cs     = gr[_REG32_CS];
+		tf->tf_cs     = gr[_REG32_CS] & 0xFFFF;
 		tf->tf_rsp    = gr[_REG32_UESP];
-		tf->tf_ss     = gr[_REG32_SS];
+		tf->tf_ss     = gr[_REG32_SS] & 0xFFFF;
 	}
 
 	if ((flags & _UC_TLSBASE) != 0)
@@ -989,10 +989,10 @@ cpu_getmcontext32(struct lwp *l, mcontex
 	__greg32_t ras_eip;
 
 	/* Save register context. */
-	gr[_REG32_GS]  = tf->tf_gs;
-	gr[_REG32_FS]  = tf->tf_fs;
-	gr[_REG32_ES]  = tf->tf_es;
-	gr[_REG32_DS]  = tf->tf_ds;
+	gr[_REG32_GS]  = tf->tf_gs & 0xFFFF;
+	gr[_REG32_FS]  = tf->tf_fs & 0xFFFF;
+	gr[_REG32_ES]  = tf->tf_es & 0xFFFF;
+	gr[_REG32_DS]  = tf->tf_ds & 0xFFFF;
 	gr[_REG32_EFL] = tf->tf_rflags;
 	gr[_REG32_EDI]    = tf->tf_rdi;
 	gr[_REG32_ESI]    = tf->tf_rsi;
@@ -1002,10 +1002,10 @@ cpu_getmcontext32(struct lwp *l, mcontex
 	gr[_REG32_ECX]    = tf->tf_rcx;
 	gr[_REG32_EAX]    = tf->tf_rax;
 	gr[_REG32_EIP]    = tf->tf_rip;
-	gr[_REG32_CS]     = tf->tf_cs;
+	gr[_REG32_CS]     = tf->tf_cs & 0xFFFF;
 	gr[_REG32_ESP]    = tf->tf_rsp;
 	gr[_REG32_UESP]   = tf->tf_rsp;
-	gr[_REG32_SS]     = tf->tf_ss;
+	gr[_REG32_SS]     = tf->tf_ss & 0xFFFF;
 	gr[_REG32_TRAPNO] = tf->tf_trapno;
 	gr[_REG32_ERR]    = tf->tf_err;
 
@@ -1166,10 +1166,10 @@ compat_13_netbsd32_sigreturn(struct lwp 
 	if (error != 0)
 		return error;
 
-	tf->tf_gs = context.sc_gs;
-	tf->tf_fs = context.sc_fs;		
-	tf->tf_es = context.sc_es;
-	tf->tf_ds = context.sc_ds;
+	tf->tf_gs = context.sc_gs & 0xFFFF;
+	tf->tf_fs = context.sc_fs & 0xFFFF;		
+	tf->tf_es = context.sc_es & 0xFFFF;
+	tf->tf_ds = context.sc_ds & 0xFFFF;
 	tf->tf_rflags = context.sc_eflags;
 	tf->tf_rdi = context.sc_edi;
 	tf->tf_rsi = context.sc_esi;
@@ -1179,9 +1179,9 @@ compat_13_netbsd32_sigreturn(struct lwp 
 	tf->tf_rcx = context.sc_ecx;
 	tf->tf_rax = context.sc_eax;
 	tf->tf_rip = context.sc_eip;
-	tf->tf_cs = context.sc_cs;
+	tf->tf_cs = context.sc_cs & 0xFFFF;
 	tf->tf_rsp = context.sc_esp;
-	tf->tf_ss = context.sc_ss;
+	tf->tf_ss = context.sc_ss & 0xFFFF;
 
 	mutex_enter(p->p_lock);
 	/* Restore signal stack. */

Index: src/sys/compat/linux/arch/amd64/linux_machdep.c
diff -u src/sys/compat/linux/arch/amd64/linux_machdep.c:1.53 src/sys/compat/linux/arch/amd64/linux_machdep.c:1.54
--- src/sys/compat/linux/arch/amd64/linux_machdep.c:1.53	Sun Oct 15 12:49:53 2017
+++ src/sys/compat/linux/arch/amd64/linux_machdep.c	Thu Oct 19 10:01:09 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_machdep.c,v 1.53 2017/10/15 12:49:53 maxv Exp $ */
+/*	$NetBSD: linux_machdep.c,v 1.54 2017/10/19 10:01:09 maxv Exp $ */
 
 /*-
  * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved.
@@ -33,7 +33,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.53 2017/10/15 12:49:53 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.54 2017/10/19 10:01:09 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -366,15 +366,15 @@ linux_sys_rt_sigreturn(struct lwp *l, co
 	mctx->__gregs[_REG_RCX] = lsigctx->rcx;
 	mctx->__gregs[_REG_RIP] = lsigctx->rip;
 	mctx->__gregs[_REG_RFLAGS] = lsigctx->eflags;
-	mctx->__gregs[_REG_CS] = lsigctx->cs;
-	mctx->__gregs[_REG_GS] = lsigctx->gs;
-	mctx->__gregs[_REG_FS] = lsigctx->fs;
+	mctx->__gregs[_REG_CS] = lsigctx->cs & 0xFFFF;
+	mctx->__gregs[_REG_GS] = lsigctx->gs & 0xFFFF;
+	mctx->__gregs[_REG_FS] = lsigctx->fs & 0xFFFF;
 	mctx->__gregs[_REG_ERR] = lsigctx->err;
 	mctx->__gregs[_REG_TRAPNO] = lsigctx->trapno;
-	mctx->__gregs[_REG_ES] = tf->tf_es;
-	mctx->__gregs[_REG_DS] = tf->tf_ds;
+	mctx->__gregs[_REG_ES] = tf->tf_es & 0xFFFF;
+	mctx->__gregs[_REG_DS] = tf->tf_ds & 0xFFFF;
 	mctx->__gregs[_REG_RSP] = lsigctx->rsp; /* XXX */
-	mctx->__gregs[_REG_SS] = tf->tf_ss;
+	mctx->__gregs[_REG_SS] = tf->tf_ss & 0xFFFF;
 
 	/*
 	 * FPU state 

Index: src/sys/compat/linux32/arch/amd64/linux32_machdep.c
diff -u src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.41 src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.42
--- src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.41	Sun Oct 15 12:49:53 2017
+++ src/sys/compat/linux32/arch/amd64/linux32_machdep.c	Thu Oct 19 10:01:09 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_machdep.c,v 1.41 2017/10/15 12:49:53 maxv Exp $ */
+/*	$NetBSD: linux32_machdep.c,v 1.42 2017/10/19 10:01:09 maxv Exp $ */
 
 /*-
  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
@@ -31,7 +31,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.41 2017/10/15 12:49:53 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.42 2017/10/19 10:01:09 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -335,10 +335,10 @@ linux32_save_sigcontext(struct lwp *l, s
 	struct pcb *pcb = lwp_getpcb(l);
 
 	/* Save register context. */
-	sc->sc_gs = tf->tf_gs;
-	sc->sc_fs = tf->tf_fs;
-	sc->sc_es = tf->tf_es;
-	sc->sc_ds = tf->tf_ds;
+	sc->sc_gs = tf->tf_gs & 0xFFFF;
+	sc->sc_fs = tf->tf_fs & 0xFFFF;
+	sc->sc_es = tf->tf_es & 0xFFFF;
+	sc->sc_ds = tf->tf_ds & 0xFFFF;
 	sc->sc_eflags = tf->tf_rflags;
 	sc->sc_edi = tf->tf_rdi;
 	sc->sc_esi = tf->tf_rsi;
@@ -349,9 +349,9 @@ linux32_save_sigcontext(struct lwp *l, s
 	sc->sc_ecx = tf->tf_rcx;
 	sc->sc_eax = tf->tf_rax;
 	sc->sc_eip = tf->tf_rip;
-	sc->sc_cs = tf->tf_cs;
+	sc->sc_cs = tf->tf_cs & 0xFFFF;
 	sc->sc_esp_at_signal = tf->tf_rsp;
-	sc->sc_ss = tf->tf_ss;
+	sc->sc_ss = tf->tf_ss & 0xFFFF;
 	sc->sc_err = tf->tf_err;
 	sc->sc_trapno = tf->tf_trapno;
 	sc->sc_cr2 = pcb->pcb_cr2;

Reply via email to