Source-Changes-HG archive

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

[src/trunk]: src/sys/uvm Disable mapping of virtual address 0 by user program...



details:   https://anonhg.NetBSD.org/src/rev/ca5ee4bbe5f2
branches:  trunk
changeset: 752190:ca5ee4bbe5f2
user:      drochner <drochner%NetBSD.org@localhost>
date:      Thu Feb 18 14:57:01 2010 +0000

description:
Disable mapping of virtual address 0 by user programs per default.
This blocks an easy exploit of kernel bugs leading to dereference
of a NULL pointer on some architectures (eg i386).
The check can be disabled in various ways:
-by CPP definitions in machine/types.h (portmaster's choice)
-by a kernel config option USER_VA0_DISABLED_DEFAULT=0
-at runtime by sysctl vm.user_va0_disabled (cannot be cleared
 at securelevel>0)

diffstat:

 sys/uvm/files.uvm |   3 +-
 sys/uvm/uvm_map.c |  63 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 63 insertions(+), 3 deletions(-)

diffs (119 lines):

diff -r abd5c85e7ceb -r ca5ee4bbe5f2 sys/uvm/files.uvm
--- a/sys/uvm/files.uvm Thu Feb 18 14:10:15 2010 +0000
+++ b/sys/uvm/files.uvm Thu Feb 18 14:57:01 2010 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.uvm,v 1.16 2009/10/21 21:12:07 rmind Exp $
+#      $NetBSD: files.uvm,v 1.17 2010/02/18 14:57:01 drochner Exp $
 
 #
 # UVM options
@@ -10,6 +10,7 @@
 defflag opt_ubc.h              UBC_STATS
 defparam opt_pagermap.h                PAGER_MAP_SIZE
 defflag                                PDPOLICY_CLOCKPRO
+defparam                       USER_VA0_DISABLED_DEFAULT
 
 file   uvm/uvm_amap.c
 file   uvm/uvm_anon.c
diff -r abd5c85e7ceb -r ca5ee4bbe5f2 sys/uvm/uvm_map.c
--- a/sys/uvm/uvm_map.c Thu Feb 18 14:10:15 2010 +0000
+++ b/sys/uvm/uvm_map.c Thu Feb 18 14:57:01 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_map.c,v 1.287 2010/02/08 19:02:33 joerg Exp $      */
+/*     $NetBSD: uvm_map.c,v 1.288 2010/02/18 14:57:01 drochner Exp $   */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.287 2010/02/08 19:02:33 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.288 2010/02/18 14:57:01 drochner Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvmhist.h"
@@ -89,6 +89,11 @@
 #include <sys/vnode.h>
 #include <sys/lockdebug.h>
 #include <sys/atomic.h>
+#ifndef __USER_VA0_IS_SAFE
+#include <sys/sysctl.h>
+#include <sys/kauth.h>
+#include "opt_user_va0_disabled_default.h"
+#endif
 
 #ifdef SYSVSHM
 #include <sys/shm.h>
@@ -168,6 +173,17 @@
 vaddr_t uvm_maxkaddr;
 #endif
 
+#ifndef __USER_VA0_IS_SAFE
+#ifndef __USER_VA0_DISABLED_DEFAULT
+#define __USER_VA0_DISABLED_DEFAULT 1
+#endif
+#ifdef USER_VA0_DISABLED_DEFAULT /* kernel config option overrides */
+#undef __USER_VA0_DISABLED_DEFAULT
+#define __USER_VA0_DISABLED_DEFAULT USER_VA0_DISABLED_DEFAULT
+#endif
+static int user_va0_disabled = __USER_VA0_DISABLED_DEFAULT;
+#endif
+
 /*
  * macros
  */
@@ -1174,6 +1190,12 @@
        KASSERT((flags & UVM_FLAG_QUANTUM) == 0 || VM_MAP_IS_KERNEL(map));
        KASSERT((size & PAGE_MASK) == 0);
 
+#ifndef __USER_VA0_IS_SAFE
+       if ((flags & UVM_FLAG_FIXED) && *startp == 0 &&
+           !VM_MAP_IS_KERNEL(map) && user_va0_disabled)
+               return EACCES;
+#endif
+
        /*
         * for pager_map, allocate the new entry first to avoid sleeping
         * for memory while we have the map locked.
@@ -5215,3 +5237,40 @@
 }
 
 #endif /* DDB || DEBUGPRINT */
+
+#ifndef __USER_VA0_IS_SAFE
+static int
+sysctl_user_va0_disabled(SYSCTLFN_ARGS)
+{
+       struct sysctlnode node;
+       int t, error;
+
+       node = *rnode;
+       node.sysctl_data = &t;
+       t = user_va0_disabled;
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (error || newp == NULL)
+               return (error);
+
+       /* lower only at securelevel < 1 */
+       if (!t && user_va0_disabled &&
+           kauth_authorize_system(l->l_cred,
+                                  KAUTH_SYSTEM_CHSYSFLAGS /* XXX */, 0,
+                                  NULL, NULL, NULL))
+               return EPERM;
+
+       user_va0_disabled = !!t;
+       return 0;
+}
+
+SYSCTL_SETUP(sysctl_uvmmap_setup, "sysctl uvmmap setup")
+{
+
+        sysctl_createv(clog, 0, NULL, NULL,
+                       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                       CTLTYPE_INT, "user_va0_disabled",
+                       SYSCTL_DESCR("Disable VA 0"),
+                       sysctl_user_va0_disabled, 0, &user_va0_disabled, 0,
+                       CTL_VM, CTL_CREATE, CTL_EOL);
+}
+#endif



Home | Main Index | Thread Index | Old Index