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