[Top][All Lists]

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

Re: RPC to self with rendez-vous leading to duplicate port destroy

From: Samuel Thibault
Subject: Re: RPC to self with rendez-vous leading to duplicate port destroy
Date: Fri, 18 Mar 2011 01:02:56 +0100
User-agent: Mutt/1.5.12-2006-07-14

Samuel Thibault, le Mon 14 Mar 2011 22:49:36 +0100, a écrit :
> > On Mar 13, 2011 5:44 PM, "Samuel Thibault" <samuel.thibault@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

in thread A:
- mach_reply_port(), which creates a reply port and returns a name for
- 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)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]