Source-Changes-HG archive

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

[src/netbsd-8]: src/sys/arch/x86/x86 Pull up following revision(s) (requested...



details:   https://anonhg.NetBSD.org/src/rev/109048ef293b
branches:  netbsd-8
changeset: 851627:109048ef293b
user:      martin <martin%NetBSD.org@localhost>
date:      Thu Apr 12 13:08:16 2018 +0000

description:
Pull up following revision(s) (requested by kamil in ticket #712):

        sys/arch/x86/x86/dbregs.c: revision 1.7-1.9

Fix the check, should be >=.

Hum, don't let userland set bit 13, because this can crash the kernel.

Add paranoid code to X86 Debug Registers

Reset certain bits in DR6 and DR7 in x86_dbregs_setup_initdbstate().
Reset X86_BREAKPOINT_CONDITION_DETECTED in DR6.
Reset X86_DR7_GENERAL_DETECT_ENABLE in DR7.

It's allowed by devices or software before the kernel boot, to
use these registers for their own purposes. Handle this paranoid case
explicitly setting the mentioned bits to zero.

Sponsored by <The NetBSD Foundation>

diffstat:

 sys/arch/x86/x86/dbregs.c |  42 ++++++++++++++++++++++++++----------------
 1 files changed, 26 insertions(+), 16 deletions(-)

diffs (76 lines):

diff -r 6c8f61ee3ebe -r 109048ef293b sys/arch/x86/x86/dbregs.c
--- a/sys/arch/x86/x86/dbregs.c Thu Apr 12 13:02:20 2018 +0000
+++ b/sys/arch/x86/x86/dbregs.c Thu Apr 12 13:08:16 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dbregs.c,v 1.6 2017/02/23 12:01:12 martin Exp $        */
+/*     $NetBSD: dbregs.c,v 1.6.6.1 2018/04/12 13:08:16 martin Exp $    */
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -43,6 +43,18 @@
 
 static struct dbreg initdbstate;
 
+#define X86_BREAKPOINT_CONDITION_DETECTED      ( \
+       X86_DR6_DR0_BREAKPOINT_CONDITION_DETECTED | \
+       X86_DR6_DR1_BREAKPOINT_CONDITION_DETECTED | \
+       X86_DR6_DR2_BREAKPOINT_CONDITION_DETECTED | \
+       X86_DR6_DR3_BREAKPOINT_CONDITION_DETECTED )
+
+#define X86_GLOBAL_BREAKPOINT  ( \
+       X86_DR7_GLOBAL_DR0_BREAKPOINT | \
+       X86_DR7_GLOBAL_DR1_BREAKPOINT | \
+       X86_DR7_GLOBAL_DR2_BREAKPOINT | \
+       X86_DR7_GLOBAL_DR3_BREAKPOINT )
+
 void
 x86_dbregs_setup_initdbstate(void)
 {
@@ -56,19 +68,17 @@
        initdbstate.dr[6] = rdr6();
        initdbstate.dr[7] = rdr7();
        /* DR8-DR15 are reserved - skip */
-}
 
-#define X86_BREAKPOINT_CONDITION_DETECTED      ( \
-       X86_DR6_DR0_BREAKPOINT_CONDITION_DETECTED | \
-       X86_DR6_DR1_BREAKPOINT_CONDITION_DETECTED | \
-       X86_DR6_DR2_BREAKPOINT_CONDITION_DETECTED | \
-       X86_DR6_DR3_BREAKPOINT_CONDITION_DETECTED )
+       /*
+        * Paranoid case.
+        *
+        * Explicitly reset some bits just in case they could be
+        * set by brave software/hardware before the kernel boot.
+        */
+       initdbstate.dr[6] &= ~X86_BREAKPOINT_CONDITION_DETECTED;
 
-#define X86_GLOBAL_BREAKPOINT  ( \
-       X86_DR7_GLOBAL_DR0_BREAKPOINT | \
-       X86_DR7_GLOBAL_DR1_BREAKPOINT | \
-       X86_DR7_GLOBAL_DR2_BREAKPOINT | \
-       X86_DR7_GLOBAL_DR3_BREAKPOINT )
+       initdbstate.dr[7] &= ~X86_DR7_GENERAL_DETECT_ENABLE;
+}
 
 void
 x86_dbregs_clear(struct lwp *l)
@@ -188,14 +198,14 @@
 
        /* Check that DR0-DR3 contain user-space address */
        for (i = 0; i < X86_DBREGS; i++)
-               if (regs->dr[i] > (vaddr_t)VM_MAXUSER_ADDRESS)
+               if (regs->dr[i] >= (vaddr_t)VM_MAXUSER_ADDRESS)
                        return EINVAL;
 
+       if (regs->dr[7] & X86_DR7_GENERAL_DETECT_ENABLE)
+               return EINVAL;
+
        /*
         * Skip checks for reserved registers (DR4-DR5, DR8-DR15).
-        *
-        * Don't validate DR6-DR7 as some bits are set by hardware and a user
-        * cannot overwrite them.
         */
 
        return 0;



Home | Main Index | Thread Index | Old Index