Source-Changes-HG archive

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

[src/trunk]: src/sys/compat Avoid re-allocations of darwin_emuldata structure...



details:   https://anonhg.NetBSD.org/src/rev/800ebad13b67
branches:  trunk
changeset: 555550:800ebad13b67
user:      manu <manu%NetBSD.org@localhost>
date:      Thu Nov 20 22:05:25 2003 +0000

description:
Avoid re-allocations of darwin_emuldata structures by COMPAT_MACH. This
caused a memory leak, and as mach_emuldata is shorter than darwin_emuldata,
it caused memory corruption.

diffstat:

 sys/compat/darwin/darwin_exec.c |  17 +++++++++++------
 sys/compat/mach/mach_exec.c     |  32 ++++++++++++++++++++++++++------
 sys/compat/mach/mach_exec.h     |   3 ++-
 3 files changed, 39 insertions(+), 13 deletions(-)

diffs (132 lines):

diff -r 46f6c702c708 -r 800ebad13b67 sys/compat/darwin/darwin_exec.c
--- a/sys/compat/darwin/darwin_exec.c   Thu Nov 20 18:43:58 2003 +0000
+++ b/sys/compat/darwin/darwin_exec.c   Thu Nov 20 22:05:25 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: darwin_exec.c,v 1.24 2003/11/18 01:40:18 manu Exp $ */
+/*     $NetBSD: darwin_exec.c,v 1.25 2003/11/20 22:05:25 manu Exp $ */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
 
 #include "opt_compat_darwin.h" /* For COMPAT_DARWIN in mach_port.h */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: darwin_exec.c,v 1.24 2003/11/18 01:40:18 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: darwin_exec.c,v 1.25 2003/11/20 22:05:25 manu Exp $");
 
 #include "opt_syscall_debug.h"
 
@@ -257,15 +257,20 @@
        /* Use parent's vmspace because our vmspace may not be setup yet */
        darwin_e_proc_init(p, parent->p_vmspace);
 
-       /* Setup the mach_emuldata part of darwin_emuldata */
-       mach_e_proc_fork(p, parent);
+       /* 
+        * Setup the mach_emuldata part of darwin_emuldata 
+        * The null third argument asks to not re-allocate 
+        * p->p_emuldata again.
+        */
+       mach_e_proc_fork1(p, parent, 0);
 
        ded1 = p->p_emuldata;
        ded2 = parent->p_emuldata;
 
-       ed1 = (char *)((u_long)ded1 + sizeof(struct mach_emuldata));
-       ed2 = (char *)((u_long)ded2 + sizeof(struct mach_emuldata));
+       ed1 = (char *)ded1 + sizeof(struct mach_emuldata);;
+       ed2 = (char *)ded2 + sizeof(struct mach_emuldata);;
        len = sizeof(struct darwin_emuldata) - sizeof(struct mach_emuldata);
+
        (void)memcpy(ed1, ed2, len);
 
        if ((ded2->ded_fakepid == 1) && (darwin_init_pid != 0)) {
diff -r 46f6c702c708 -r 800ebad13b67 sys/compat/mach/mach_exec.c
--- a/sys/compat/mach/mach_exec.c       Thu Nov 20 18:43:58 2003 +0000
+++ b/sys/compat/mach/mach_exec.c       Thu Nov 20 22:05:25 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mach_exec.c,v 1.38 2003/11/18 15:57:13 manu Exp $       */
+/*     $NetBSD: mach_exec.c,v 1.39 2003/11/20 22:05:25 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.38 2003/11/18 15:57:13 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.39 2003/11/20 22:05:25 manu Exp $");
 
 #include "opt_syscall_debug.h"
 
@@ -199,15 +199,30 @@
        return;
 }
 
-void 
+void
 mach_e_proc_fork(p, parent)
        struct proc *p;
        struct proc *parent;
 {
+       mach_e_proc_fork1(p, parent, 1);        
+       return;
+}
+
+void 
+mach_e_proc_fork1(p, parent, allocate)
+       struct proc *p;
+       struct proc *parent;
+       int allocate;
+{
        struct mach_emuldata *med1;
        struct mach_emuldata *med2;
 
-       p->p_emuldata = NULL;
+       /*
+        * For Darwin binaries, p->p_emuldata has already been
+        * allocated, no need to throw it away and allocate it again.
+        */
+       if (allocate)
+               p->p_emuldata = NULL;
 
        /* Use parent's vmspace because our vmspace may not be setup yet */
        mach_e_proc_init(p, parent->p_vmspace);
@@ -238,13 +253,18 @@
 
        /*
         * For Darwin binaries, p->p_emuldata is aways allocated:
-        * from the previous programm if it had the same emulation,
+        * from the previous program if it had the same emulation,
         * or from darwin_e_proc_exec(). In the latter situation, 
         * everything has been set to zero.
         */
-       if (!p->p_emuldata) 
+       if (!p->p_emuldata) {
+#ifdef DIAGNOSTIC
+               if (p->p_emul != &emul_mach)
+                       printf("mach_emuldata allocated for non Mach binary\n");
+#endif
                p->p_emuldata = malloc(sizeof(struct mach_emuldata),
                    M_EMULDATA, M_WAITOK | M_ZERO);
+       }
 
        med = (struct mach_emuldata *)p->p_emuldata;
 
diff -r 46f6c702c708 -r 800ebad13b67 sys/compat/mach/mach_exec.h
--- a/sys/compat/mach/mach_exec.h       Thu Nov 20 18:43:58 2003 +0000
+++ b/sys/compat/mach/mach_exec.h       Thu Nov 20 22:05:25 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mach_exec.h,v 1.22 2003/11/18 14:11:33 manu Exp $       */
+/*     $NetBSD: mach_exec.h,v 1.23 2003/11/20 22:05:25 manu Exp $       */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -71,6 +71,7 @@
 void mach_e_proc_exit(struct proc *);
 void mach_e_proc_exec(struct proc *, struct exec_package *);
 void mach_e_proc_fork(struct proc *, struct proc *);
+void mach_e_proc_fork1(struct proc *, struct proc *, int);
 
 extern const struct emul emul_mach;
 



Home | Main Index | Thread Index | Old Index