Source-Changes-HG archive

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

[src/trunk]: src/sys/compat/mach Fix some panics caused by incorrect Mach exc...



details:   https://anonhg.NetBSD.org/src/rev/b6a51b33fcca
branches:  trunk
changeset: 556039:b6a51b33fcca
user:      manu <manu%NetBSD.org@localhost>
date:      Sat Dec 06 15:15:19 2003 +0000

description:
Fix some panics caused by incorrect Mach exceptions reference counts

diffstat:

 sys/compat/mach/mach_exec.c |  34 ++++++++++++++++++++++------------
 sys/compat/mach/mach_task.c |  42 +++++++++++++++++++++++++++++++-----------
 2 files changed, 53 insertions(+), 23 deletions(-)

diffs (165 lines):

diff -r dc7e26592005 -r b6a51b33fcca sys/compat/mach/mach_exec.c
--- a/sys/compat/mach/mach_exec.c       Sat Dec 06 14:17:13 2003 +0000
+++ b/sys/compat/mach/mach_exec.c       Sat Dec 06 15:15:19 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mach_exec.c,v 1.42 2003/12/05 21:12:43 jdolecek Exp $   */
+/*     $NetBSD: mach_exec.c,v 1.43 2003/12/06 15:15:19 manu Exp $       */
 
 /*-
  * Copyright (c) 2001-2003 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.42 2003/12/05 21:12:43 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.43 2003/12/06 15:15:19 manu Exp $");
 
 #include "opt_syscall_debug.h"
 
@@ -216,6 +216,7 @@
 {
        struct mach_emuldata *med1;
        struct mach_emuldata *med2;
+       int i;
 
        /*
         * For Darwin binaries, p->p_emuldata has already been
@@ -230,8 +231,17 @@
        med1 = p->p_emuldata;
        med2 = parent->p_emuldata;
 
-       /* Exception ports are inherited between forks. */
-       (void)memcpy(med1->med_exc, med2->med_exc, sizeof(med1->med_exc));
+       /* 
+        * Exception ports are inherited between forks,
+        * but we need to double their reference counts, 
+        * since the ports are referenced by rights in the
+        * parent and in the child.
+        */
+       for (i = 0; i <= MACH_EXC_MAX; i++) {
+               med1->med_exc[i] = med2->med_exc[i];
+               if (med1->med_exc[i] !=  NULL)
+                       med1->med_exc[i]->mp_refcount *= 2;
+       }
 
        return;
 }
@@ -344,6 +354,7 @@
 {
        struct mach_emuldata *med;
        struct mach_right *mr;
+       int i;
 
        mach_semaphore_cleanup(p);
 
@@ -354,18 +365,17 @@
                mach_right_put_exclocked(mr, MACH_PORT_TYPE_ALL_RIGHTS);
        lockmgr(&med->med_rightlock, LK_RELEASE, NULL);
 
-       if (--med->med_bootstrap->mp_refcount == 0)
+       if (--med->med_bootstrap->mp_refcount <= 0)
                mach_port_put(med->med_bootstrap);
-       if (--med->med_kernel->mp_refcount == 0) 
+       if (--med->med_kernel->mp_refcount <= 0) 
                mach_port_put(med->med_kernel);
-       if (--med->med_host->mp_refcount == 0)  
+       if (--med->med_host->mp_refcount <= 0)  
                mach_port_put(med->med_host);  
 
-       /*
-        * Exceptions ports have been released when we
-        * released all the ports rights asociated with
-        * the process, so do not touch them now. 
-        */
+       for (i = 0; i <= MACH_EXC_MAX; i++)
+               if ((med->med_exc[i] != NULL) &&
+                   (--med->med_exc[i]->mp_refcount <= 0))
+                       mach_port_put(med->med_exc[i]);
 
        free(med, M_EMULDATA);
        p->p_emuldata = NULL;
diff -r dc7e26592005 -r b6a51b33fcca sys/compat/mach/mach_task.c
--- a/sys/compat/mach/mach_task.c       Sat Dec 06 14:17:13 2003 +0000
+++ b/sys/compat/mach/mach_task.c       Sat Dec 06 15:15:19 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mach_task.c,v 1.44 2003/11/30 20:42:03 manu Exp $ */
+/*     $NetBSD: mach_task.c,v 1.45 2003/12/06 15:15:19 manu Exp $ */
 
 /*-
  * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
 #include "opt_compat_darwin.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.44 2003/11/30 20:42:03 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.45 2003/12/06 15:15:19 manu Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -73,6 +73,9 @@
 
 #define ISSET(t, f)     ((t) & (f))
 
+static void 
+update_exception_port(struct mach_emuldata *, int exc, struct mach_port *);
+
 int 
 mach_task_get_special_port(args)
        struct mach_trap_args *args;
@@ -400,6 +403,23 @@
        return 0;
 }
 
+static void 
+update_exception_port(med, exc, mp)
+       struct mach_emuldata *med;
+       int exc;
+       struct mach_port *mp;
+{
+       if (med->med_exc[exc] != NULL) {
+               med->med_exc[exc]->mp_refcount--;
+               if (med->med_exc[exc]->mp_refcount <= 0)
+                       mach_port_put(med->med_exc[exc]);
+       }
+       med->med_exc[exc] = mp;
+       mp->mp_refcount++;
+
+       return;
+}
+
 int
 mach_task_set_exception_ports(args)
        struct mach_trap_args *args;
@@ -429,23 +449,23 @@
 
        med = tl->l_proc->p_emuldata;
        if (req->req_mask & MACH_EXC_MASK_BAD_ACCESS)
-               med->med_exc[MACH_EXC_BAD_ACCESS] = mp;
+               update_exception_port(med, MACH_EXC_BAD_ACCESS, mp);
        if (req->req_mask & MACH_EXC_MASK_BAD_INSTRUCTION)
-               med->med_exc[MACH_EXC_BAD_INSTRUCTION] = mp;
+               update_exception_port(med, MACH_EXC_BAD_INSTRUCTION, mp);
        if (req->req_mask & MACH_EXC_MASK_ARITHMETIC) 
-               med->med_exc[MACH_EXC_ARITHMETIC] = mp;
+               update_exception_port(med, MACH_EXC_ARITHMETIC, mp);
        if (req->req_mask & MACH_EXC_MASK_EMULATION)
-               med->med_exc[MACH_EXC_EMULATION] = mp;
+               update_exception_port(med, MACH_EXC_EMULATION, mp);
        if (req->req_mask & MACH_EXC_MASK_SOFTWARE)
-               med->med_exc[MACH_EXC_SOFTWARE] = mp;
+               update_exception_port(med, MACH_EXC_SOFTWARE, mp);
        if (req->req_mask & MACH_EXC_MASK_BREAKPOINT)
-               med->med_exc[MACH_EXC_BREAKPOINT] = mp;
+               update_exception_port(med, MACH_EXC_BREAKPOINT, mp);
        if (req->req_mask & MACH_EXC_MASK_SYSCALL)
-               med->med_exc[MACH_EXC_SYSCALL] = mp;
+               update_exception_port(med, MACH_EXC_SYSCALL, mp);
        if (req->req_mask & MACH_EXC_MASK_MACH_SYSCALL)
-               med->med_exc[MACH_EXC_MACH_SYSCALL] = mp;
+               update_exception_port(med, MACH_EXC_MACH_SYSCALL, mp);
        if (req->req_mask & MACH_EXC_MASK_RPC_ALERT)
-               med->med_exc[MACH_EXC_RPC_ALERT] = mp;
+               update_exception_port(med, MACH_EXC_RPC_ALERT, mp);
 
 #ifdef DEBUG_MACH
        if (req->req_mask & (MACH_EXC_ARITHMETIC | 



Home | Main Index | Thread Index | Old Index