Module Name:    src
Committed By:   reinoud
Date:           Tue Dec 20 15:39:36 UTC 2011

Modified Files:
        src/lib/libc/sys: mmap.2
        src/sys/sys: mman.h proc.h
        src/sys/uvm: uvm_extern.h uvm_map.c uvm_mmap.c

Log Message:
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..


To generate a diff of this commit:
cvs rdiff -u -r1.44 -r1.45 src/lib/libc/sys/mmap.2
cvs rdiff -u -r1.42 -r1.43 src/sys/sys/mman.h
cvs rdiff -u -r1.311 -r1.312 src/sys/sys/proc.h
cvs rdiff -u -r1.176 -r1.177 src/sys/uvm/uvm_extern.h
cvs rdiff -u -r1.307 -r1.308 src/sys/uvm/uvm_map.c
cvs rdiff -u -r1.139 -r1.140 src/sys/uvm/uvm_mmap.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/sys/mmap.2
diff -u src/lib/libc/sys/mmap.2:1.44 src/lib/libc/sys/mmap.2:1.45
--- src/lib/libc/sys/mmap.2:1.44	Sat Oct 15 22:03:03 2011
+++ src/lib/libc/sys/mmap.2	Tue Dec 20 15:39:35 2011
@@ -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 @@ other processes using
 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

Index: src/sys/sys/mman.h
diff -u src/sys/sys/mman.h:1.42 src/sys/sys/mman.h:1.43
--- src/sys/sys/mman.h:1.42	Tue Nov 18 22:13:49 2008
+++ src/sys/sys/mman.h	Tue Dec 20 15:39:35 2011
@@ -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 @@ typedef	__off_t		off_t;		/* file offset 
 #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).
  */

Index: src/sys/sys/proc.h
diff -u src/sys/sys/proc.h:1.311 src/sys/sys/proc.h:1.312
--- src/sys/sys/proc.h:1.311	Fri Oct 21 02:07:07 2011
+++ src/sys/sys/proc.h	Tue Dec 20 15:39:35 2011
@@ -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 @@ struct proc {
 #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 */
 
 /*

Index: src/sys/uvm/uvm_extern.h
diff -u src/sys/uvm/uvm_extern.h:1.176 src/sys/uvm/uvm_extern.h:1.177
--- src/sys/uvm/uvm_extern.h:1.176	Thu Sep  1 06:40:28 2011
+++ src/sys/uvm/uvm_extern.h	Tue Dec 20 15:39:35 2011
@@ -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			uvmspace_unshare(struct lwp *);
 
 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 *);

Index: src/sys/uvm/uvm_map.c
diff -u src/sys/uvm/uvm_map.c:1.307 src/sys/uvm/uvm_map.c:1.308
--- src/sys/uvm/uvm_map.c:1.307	Tue Dec 20 13:47:38 2011
+++ src/sys/uvm/uvm_map.c	Tue Dec 20 15:39:35 2011
@@ -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 @@ nomerge:
 		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_checkprot(struct vm_map *map, va
 }
 
 /*
+ * 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

Index: src/sys/uvm/uvm_mmap.c
diff -u src/sys/uvm/uvm_mmap.c:1.139 src/sys/uvm/uvm_mmap.c:1.140
--- src/sys/uvm/uvm_mmap.c:1.139	Fri Oct 14 09:23:31 2011
+++ src/sys/uvm/uvm_mmap.c	Tue Dec 20 15:39:35 2011
@@ -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 @@ sys_mmap(struct lwp *l, const struct sys
 		/* 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);
 

Reply via email to