Samuel Thibault, le Mon 14 Mar 2011 22:49:36 +0100, a écrit : > > On Mar 13, 2011 5:44 PM, "Samuel Thibault" <samuel.thiba...@gnu.org> wrote: > > > - diskfs_S_dir_lookup is called, which for some reason ends up calling > > > - fshelp_fetch_root(), which calls > > > - reauth(), which calls > > > - mach_reply_port() to get a rendez-vous port, and then issues > > > - io_reauthenticate() with that port on ext2fs itself (since it's the > > > root of the system), thus triggering a call to: > > > - diskfs_S_io_reauthenticate() in another thread. There, the > > > rendez-vous port is thus the same as the reply port obtained above, > > > with the *same name*. > > > - reauth() destroys the rendez-vous port (and thus the name!) > > > - a bit later, diskfs_S_io_reauthenticate has finished its work, > > > and deallocates its rendez-vous port. But the name doesn't exist any > > > more. Bad. > > > > I think the second call to reauth should use a second, newly-created, > > rendezvous port. Why doesn't it? > > There is only one reauth here, it's ext2fs itself reauthenticating an > fd to itself, to be used by fshelp_fetch_root for some setuid program > execution. Thus the same name since it's the same port, which is wanted > precisely since that's a rendez-vous port.
To rephrase it, what happens is completely inside ext2fs in two separate threads: in thread A: - mach_reply_port(), which creates a reply port and returns a name for it - send right on this port is given to a io_reauthenticate() RPC to self, handled by thread B - after io_reauthenticate() returns, mach_port_destroy is called to free the receive right and destroy the port in the meanwhile, in thread B - the io_reauthenticate() handler receives then send right, under the _same name_ as in thread A (that's what Mach does when a task already has some rights on a port) - io_reauthenticate does its stuff, and eventually calls mach_port_deallocate() to free the send right. Problem: if A is a bit faster, the name doesn't exist any more... Maybe mach_port_mod_refs(task, name, MACH_PORT_RIGHT_RECEIVE, -1) should simply be used to drop the receive right without destroying the name when the send right is still there? I'll be testing that. (BTW, I'm not getting any double-deallocation issue on buildds any more with this patch) Samuel