Module Name:    src
Committed By:   reinoud
Date:           Tue Dec 20 15:41:50 UTC 2011

Modified Files:
        src/sys/arch/x86/x86: syscall.c

Log Message:
Part 2 - x86 implementation of MAP_NOSYSCALLS

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.5 -r1.6 src/sys/arch/x86/x86/syscall.c

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

Modified files:

Index: src/sys/arch/x86/x86/syscall.c
diff -u src/sys/arch/x86/x86/syscall.c:1.5 src/sys/arch/x86/x86/syscall.c:1.6
--- src/sys/arch/x86/x86/syscall.c:1.5	Sun Sep  4 21:14:49 2011
+++ src/sys/arch/x86/x86/syscall.c	Tue Dec 20 15:41:50 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: syscall.c,v 1.5 2011/09/04 21:14:49 christos Exp $	*/
+/*	$NetBSD: syscall.c,v 1.6 2011/12/20 15:41:50 reinoud Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2009 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.5 2011/09/04 21:14:49 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.6 2011/12/20 15:41:50 reinoud Exp $");
 
 #include "opt_sa.h"
 
@@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: syscall.c,v 
 #include <sys/sa.h>
 #include <sys/savar.h>
 #include <sys/ktrace.h>
+#include <sys/mman.h>
 #include <sys/syscall.h>
 #include <sys/syscallvar.h>
 #include <sys/syscall_stats.h>
@@ -105,8 +106,9 @@ syscall(struct trapframe *frame)
 	const struct sysent *callp;
 	struct proc *p;
 	struct lwp *l;
+	struct vm_map *map;
 	int error;
-	register_t code, rval[2];
+	register_t code, rval[2], rip_call;
 #ifdef __x86_64__
 	/* Verify that the syscall args will fit in the trapframe space */
 	CTASSERT(offsetof(struct trapframe, tf_arg9) >=
@@ -120,6 +122,39 @@ syscall(struct trapframe *frame)
 	p = l->l_proc;
 	LWP_CACHE_CREDS(l, p);
 
+	/*
+	 * The offset to adjust the PC by depends on whether we entered the
+	 * kernel through the trap or call gate.  We saved the instruction
+	 * size in tf_err on entry.
+	 */
+	rip_call = X86_TF_RIP(frame) - frame->tf_err;
+
+	/* are we allowed to execute system calls in this memory space? */
+	if (p->p_flag & PK_CHKNOSYSCALL) {
+		map = &(p->p_vmspace->vm_map);
+		vm_map_lock(map);
+
+		if (uvm_map_checkattr(map, rip_call, rip_call + frame->tf_err,
+					MAP_NOSYSCALLS)) {
+			ksiginfo_t ksi;
+
+			vm_map_unlock(map);
+			X86_TF_RIP(frame) = rip_call;
+
+			/* treat as illegal instruction */
+			KSI_INIT_TRAP(&ksi);
+			ksi.ksi_signo = SIGILL;
+			ksi.ksi_code = ILL_ILLTRP;
+			ksi.ksi_addr = (void *) X86_TF_RIP(frame);
+			ksi.ksi_trap = 0; /* XXX ? */
+			trapsignal(l, &ksi);
+			userret(l);
+			return;
+		}
+
+		vm_map_unlock(map);
+	}
+
 	code = X86_TF_RAX(frame) & (SYS_NSYSENT - 1);
 	callp = p->p_emul->e_sysent + code;
 
@@ -173,12 +208,7 @@ syscall(struct trapframe *frame)
 	} else {
 		switch (error) {
 		case ERESTART:
-			/*
-			 * The offset to adjust the PC by depends on whether we
-			 * entered the kernel through the trap or call gate.
-			 * We saved the instruction size in tf_err on entry.
-			 */
-			X86_TF_RIP(frame) -= frame->tf_err;
+			X86_TF_RIP(frame) = rip_call;
 			break;
 		case EJUSTRETURN:
 			/* nothing to do */

Reply via email to