Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/x86/x86 Part 2 - x86 implementation of MAP_NOSYSCALLS
details: https://anonhg.NetBSD.org/src/rev/f35c2961ab60
branches: trunk
changeset: 772143:f35c2961ab60
user: reinoud <reinoud%NetBSD.org@localhost>
date: Tue Dec 20 15:41:50 2011 +0000
description:
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..
diffstat:
sys/arch/x86/x86/syscall.c | 48 +++++++++++++++++++++++++++++++++++++--------
1 files changed, 39 insertions(+), 9 deletions(-)
diffs (91 lines):
diff -r bd3f6296f195 -r f35c2961ab60 sys/arch/x86/x86/syscall.c
--- a/sys/arch/x86/x86/syscall.c Tue Dec 20 15:41:01 2011 +0000
+++ b/sys/arch/x86/x86/syscall.c Tue Dec 20 15:41:50 2011 +0000
@@ -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 @@
#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 @@
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 @@
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 @@
} 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 */
Home |
Main Index |
Thread Index |
Old Index