Source-Changes-HG archive

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

[src/trunk]: src/sys Always mask the 16 bits of the segregs in the trapframe....



details:   https://anonhg.NetBSD.org/src/rev/1b48c75cb7cc
branches:  trunk
changeset: 827190:1b48c75cb7cc
user:      maxv <maxv%NetBSD.org@localhost>
date:      Thu Oct 19 10:01:09 2017 +0000

description:
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)

diffstat:

 sys/arch/amd64/amd64/machdep.c                  |   6 +-
 sys/arch/amd64/amd64/netbsd32_machdep.c         |  68 ++++++++++++------------
 sys/compat/linux/arch/amd64/linux_machdep.c     |  16 ++--
 sys/compat/linux32/arch/amd64/linux32_machdep.c |  16 ++--
 4 files changed, 54 insertions(+), 52 deletions(-)

diffs (277 lines):

diff -r c05801e679b9 -r 1b48c75cb7cc sys/arch/amd64/amd64/machdep.c
--- a/sys/arch/amd64/amd64/machdep.c    Thu Oct 19 09:32:01 2017 +0000
+++ b/sys/arch/amd64/amd64/machdep.c    Thu Oct 19 10:01:09 2017 +0000
@@ -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 @@
        KASSERT(l == curlwp);
 
        tf = l->l_md.md_regs;
+       fssel &= 0xFFFF;
+       gssel &= 0xFFFF;
 
        pcb = lwp_getpcb(l);
        kpreempt_disable();
diff -r c05801e679b9 -r 1b48c75cb7cc sys/arch/amd64/amd64/netbsd32_machdep.c
--- a/sys/arch/amd64/amd64/netbsd32_machdep.c   Thu Oct 19 09:32:01 2017 +0000
+++ b/sys/arch/amd64/amd64/netbsd32_machdep.c   Thu Oct 19 10:01:09 2017 +0000
@@ -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 @@
        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 @@
        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 @@
 
        /* 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 @@
        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 @@
        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 @@
                        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 @@
                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 @@
        __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 @@
        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 @@
        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 @@
        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. */
diff -r c05801e679b9 -r 1b48c75cb7cc sys/compat/linux/arch/amd64/linux_machdep.c
--- a/sys/compat/linux/arch/amd64/linux_machdep.c       Thu Oct 19 09:32:01 2017 +0000
+++ b/sys/compat/linux/arch/amd64/linux_machdep.c       Thu Oct 19 10:01:09 2017 +0000
@@ -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 @@
        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 
diff -r c05801e679b9 -r 1b48c75cb7cc sys/compat/linux32/arch/amd64/linux32_machdep.c
--- a/sys/compat/linux32/arch/amd64/linux32_machdep.c   Thu Oct 19 09:32:01 2017 +0000
+++ b/sys/compat/linux32/arch/amd64/linux32_machdep.c   Thu Oct 19 10:01:09 2017 +0000
@@ -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 @@
        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 @@
        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;



Home | Main Index | Thread Index | Old Index