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