Source-Changes-HG archive

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

[src/trunk]: src Add a MAP_NOSYSCALLS flag to mmap. This flag prohibits execu...



details:   https://anonhg.NetBSD.org/src/rev/f1d1db2a4856
branches:  trunk
changeset: 772141:f1d1db2a4856
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Tue Dec 20 15:39:35 2011 +0000

description:
Add a MAP_NOSYSCALLS flag to mmap. This flag prohibits executing of system
calls from the mapped region. This can be used for emulation perposed or for
extra security in the case of generated code.

Its implemented by adding mapping-attributes to each uvm_map_entry. These can
then be queried when needed.

Currently the MAP_NOSYSCALLS is only implemented for x86 but other
architectures are easy to adapt; see the sys/arch/x86/x86/syscall.c patch.
Port maintainers are encouraged to add them for their processor ports too.
When this feature is not yet implemented for an architecture the
MAP_NOSYSCALLS is simply ignored with virtually no cpu cost..

diffstat:

 lib/libc/sys/mmap.2  |   5 ++-
 sys/sys/mman.h       |  10 +++++-
 sys/sys/proc.h       |   3 +-
 sys/uvm/uvm_extern.h |   7 +++-
 sys/uvm/uvm_map.c    |  82 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 sys/uvm/uvm_mmap.c   |  21 ++++++++++++-
 6 files changed, 120 insertions(+), 8 deletions(-)

diffs (233 lines):

diff -r 506ad07aa0fc -r f1d1db2a4856 lib/libc/sys/mmap.2
--- a/lib/libc/sys/mmap.2       Tue Dec 20 13:47:38 2011 +0000
+++ b/lib/libc/sys/mmap.2       Tue Dec 20 15:39:35 2011 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: mmap.2,v 1.44 2011/10/15 22:03:03 rmind Exp $
+.\"    $NetBSD: mmap.2,v 1.45 2011/12/20 15:39:35 reinoud Exp $
 .\"
 .\" Copyright (c) 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -180,6 +180,9 @@
 will be seen.
 .It Dv MAP_SHARED
 Modifications are shared.
+.It Dv MAP_NOSYSCALLS
+No system calls are to be allowed from within this mapped region. They instead
+generate an illegal instruction signal.
 .El
 .Pp
 The
diff -r 506ad07aa0fc -r f1d1db2a4856 sys/sys/mman.h
--- a/sys/sys/mman.h    Tue Dec 20 13:47:38 2011 +0000
+++ b/sys/sys/mman.h    Tue Dec 20 15:39:35 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mman.h,v 1.42 2008/11/18 22:13:49 ad Exp $     */
+/*     $NetBSD: mman.h,v 1.43 2011/12/20 15:39:35 reinoud Exp $        */
 
 /*-
  * Copyright (c) 1982, 1986, 1993
@@ -98,6 +98,14 @@
 #define        MAP_STACK       0x2000  /* allocated from memory, swap space (stack) */
 
 /*
+ * Map attributes 0x00010000 till 0x00ff0000
+ */
+#define MAP_ATTR(n)            ((n) << MAP_ATTRIB_SHIFT)
+#define MAP_ATTRIB_SHIFT       16
+#define MAP_ATTRIB_MASK                MAP_ATTR(0xff)
+#define MAP_NOSYSCALLS         MAP_ATTR(0x01) /* no syscalls allowed */
+
+/*
  * Alignment (expressed in log2).  Must be >= log2(PAGE_SIZE) and
  * < # bits in a pointer (26 (acorn26), 32 or 64).
  */
diff -r 506ad07aa0fc -r f1d1db2a4856 sys/sys/proc.h
--- a/sys/sys/proc.h    Tue Dec 20 13:47:38 2011 +0000
+++ b/sys/sys/proc.h    Tue Dec 20 15:39:35 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: proc.h,v 1.311 2011/10/21 02:07:07 christos Exp $      */
+/*     $NetBSD: proc.h,v 1.312 2011/12/20 15:39:35 reinoud Exp $       */
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -353,6 +353,7 @@
 #define        PK_NOCLDWAIT    0x00020000 /* No zombies if child dies */
 #define        PK_32           0x00040000 /* 32-bit process (used on 64-bit kernels) */
 #define        PK_CLDSIGIGN    0x00080000 /* Process is ignoring SIGCHLD */
+#define PK_CHKNOSYSCALL 0x00100000 /* Process needs NOSYSCALL checking */
 #define        PK_MARKER       0x80000000 /* Is a dummy marker process */
 
 /*
diff -r 506ad07aa0fc -r f1d1db2a4856 sys/uvm/uvm_extern.h
--- a/sys/uvm/uvm_extern.h      Tue Dec 20 13:47:38 2011 +0000
+++ b/sys/uvm/uvm_extern.h      Tue Dec 20 15:39:35 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_extern.h,v 1.176 2011/09/01 06:40:28 matt Exp $    */
+/*     $NetBSD: uvm_extern.h,v 1.177 2011/12/20 15:39:35 reinoud Exp $ */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -680,6 +680,11 @@
 
 void                   uvm_whatis(uintptr_t, void (*)(const char *, ...));
 
+bool                   uvm_map_setattr(struct vm_map *, vaddr_t,
+                           vaddr_t, uint32_t);
+bool                   uvm_map_checkattr(struct vm_map *, vaddr_t,
+                           vaddr_t, uint32_t);
+
 /* uvm_meter.c */
 int                    uvm_sysctl(int *, u_int, void *, size_t *,
                            void *, size_t, struct proc *);
diff -r 506ad07aa0fc -r f1d1db2a4856 sys/uvm/uvm_map.c
--- a/sys/uvm/uvm_map.c Tue Dec 20 13:47:38 2011 +0000
+++ b/sys/uvm/uvm_map.c Tue Dec 20 15:39:35 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_map.c,v 1.307 2011/12/20 13:47:38 yamt Exp $       */
+/*     $NetBSD: uvm_map.c,v 1.308 2011/12/20 15:39:35 reinoud Exp $    */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.307 2011/12/20 13:47:38 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.308 2011/12/20 15:39:35 reinoud Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvmhist.h"
@@ -1672,6 +1672,7 @@
                new_entry->protection = prot;
                new_entry->max_protection = maxprot;
                new_entry->inheritance = inherit;
+               new_entry->map_attrib = 0;              /* XXX could be passed too */
                new_entry->wired_count = 0;
                new_entry->advice = advice;
                if (flags & UVM_FLAG_OVERLAY) {
@@ -4121,6 +4122,83 @@
 }
 
 /*
+ * uvm_map_setattr: set uvm-external mapping attributes in map
+ *
+ * => map must be read or write locked by caller.
+ */
+
+bool
+uvm_map_setattr(struct vm_map *map, vaddr_t start, vaddr_t end,
+    uint32_t map_attrib)
+{
+       struct vm_map_entry *entry;
+       struct vm_map_entry *tmp_entry;
+
+       if (!uvm_map_lookup_entry(map, start, &tmp_entry)) {
+               return (false);
+       }
+       entry = tmp_entry;
+       while (start < end) {
+               if (entry == &map->header) {
+                       return (false);
+               }
+
+               /*
+                * no holes allowed
+                */
+
+               if (start < entry->start) {
+                       return (false);
+               }
+
+               /* set attributes associated with entry */
+
+               entry->map_attrib = map_attrib;
+
+               start = entry->end;
+               entry = entry->next;
+       }
+       return (true);
+}
+
+/*
+ * uvm_map_checkattr: check attribute bits in map
+ *
+ * => check if attribute is present in the region.
+ * => map must be read or write locked by caller.
+ */
+
+bool
+uvm_map_checkattr(struct vm_map *map, vaddr_t start, vaddr_t end,
+    uint32_t map_attrib)
+{
+       struct vm_map_entry *entry;
+       struct vm_map_entry *tmp_entry;
+
+       if (!uvm_map_lookup_entry(map, start, &tmp_entry))
+               return (false);
+
+       entry = tmp_entry;
+       while (start < end) {
+               if (entry == &map->header)
+                       return (false);
+
+               /*
+                * check attribute associated with entry
+                */
+
+               if ((entry->map_attrib & map_attrib) == map_attrib) {
+                       return (true);
+               }
+
+               start = entry->end;
+               entry = entry->next;
+       }
+       return (false);
+}
+
+
+/*
  * uvmspace_alloc: allocate a vmspace structure.
  *
  * - structure includes vm_map and pmap
diff -r 506ad07aa0fc -r f1d1db2a4856 sys/uvm/uvm_mmap.c
--- a/sys/uvm/uvm_mmap.c        Tue Dec 20 13:47:38 2011 +0000
+++ b/sys/uvm/uvm_mmap.c        Tue Dec 20 15:39:35 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_mmap.c,v 1.139 2011/10/14 09:23:31 hannken Exp $   */
+/*     $NetBSD: uvm_mmap.c,v 1.140 2011/12/20 15:39:35 reinoud Exp $   */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.139 2011/10/14 09:23:31 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.140 2011/12/20 15:39:35 reinoud Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_pax.h"
@@ -547,6 +547,23 @@
                /* remember to add offset */
                *retval = (register_t)(addr + pageoff);
 
+       /*
+        * Support for map attributes; XXX preferably given as an
+        * extra parameter to uvm_map or merged with uvmflag.
+        * Implemented now as setting parameters after the mapping.
+        */
+       if (error == 0) {
+               if (flags & MAP_ATTRIB_MASK) {
+                       if (!uvm_map_setattr(&p->p_vmspace->vm_map,
+                                       addr, addr + size,
+                                       flags & MAP_ATTRIB_MASK))
+                               panic("uvm_setattr failed?");
+               }
+               /* record if we need optimization for system call checking */
+               if (flags & MAP_NOSYSCALLS)
+                       p->p_flag |= PK_CHKNOSYSCALL;
+       }
+
        if (fp != NULL)
                fd_putfile(fd);
 



Home | Main Index | Thread Index | Old Index