This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: fork: mach_port_mod_refs: EKERN_UREFS_OWERFLOW


Hi!

On Thu, 08 Sep 2011 12:40:30 +0200, Thomas Schwinge <thomas@schwinge.name> wrote:
> This is about fork in glibc.  It's leaking port rights.

(We're not leaking port rights, but we're Âhandling user reference counts
incorrectlyÂ, as I corrected myself later on.)

> Roland, thanks for the good source code commentation, which is mostly
> up-to-date; this has helped a lot for understanding!
> 
> 
> On Mon, 22 Nov 2010 11:56:45 +0100, Samuel Thibault <samuel.thibault@gnu.org> wrote:
> > Thomas Schwinge, le Mon 22 Nov 2010 09:38:24 +0100, a Ãcrit :
> > >        463            (err = __mach_port_mod_refs (newtask, ss->thread,
> > >        464                                         MACH_PORT_RIGHT_SEND,
> > >        465                                         thread_refs)))
> > 
> > and
> > 
> > thread_refs = 65534
> > 
> > it happens that gnumach has
> > 
> > #define	MACH_PORT_UREFS_MAX	((mach_port_urefs_t) ((1 << 16) - 1))
> > 
> > So the original issues seems to be that thread_refs went in the sky.
> 
> Indeed there are port leaks in this code.  In the *parent*, mind you.
> And what happens is that after enough fork invocations, in the parent,
> the mach_thread_self (ss->thread above) user reference count will be
> 65534, and then the mach_port_mod_refs for newtask must fail, as it
> already has got one right, but can't add another 65534 due to
> MACH_PORT_UREFS_MAX.
> 
> If you now consider that this bug was triggered by DejaGnu's runtest,
> which ``endlessly'' invokes GCC and other stuff on thousands of C test
> files in the GCC testsuite, this does make sense.  The parent runtest
> process is invoking fork all the time, so the leak(s) just add up in the
> parent.

Here is a patch.  OK to commit?

	* sysdeps/mach/hurd/fork.c (__fork): Install correct number of
	send rights for its main user thread in NEWTASK.

diff --git sysdeps/mach/hurd/fork.c sysdeps/mach/hurd/fork.c
index 644838c..0e29f0f 100644
--- sysdeps/mach/hurd/fork.c
+++ sysdeps/mach/hurd/fork.c
@@ -454,14 +453,10 @@ __fork (void)
 	  (err = __mach_port_insert_right (newtask, ss->thread,
 					   thread, MACH_MSG_TYPE_COPY_SEND)))
 	LOSE;
-      /* We have one extra user reference created at the beginning of this
-	 function, accounted for by mach_port_names (and which will thus be
-	 accounted for in the child below).  This extra right gets consumed
-	 in the child by the store into _hurd_sigthread in the child fork.  */
       if (thread_refs > 1 &&
 	  (err = __mach_port_mod_refs (newtask, ss->thread,
 				       MACH_PORT_RIGHT_SEND,
-				       thread_refs)))
+				       thread_refs - 1)))
 	LOSE;
       if ((_hurd_msgport_thread != MACH_PORT_NULL) /* Let user have none.  */
 	  && ((err = __mach_port_deallocate (newtask, _hurd_msgport_thread)) ||


GrÃÃe,
 Thomas

Attachment: pgp00000.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]