Good catch. As Roland notes the old code here has the restart race bug. Also it was probably a leak because I think nothing here wa counting he new make send instance the way we normally wrap all uses of make send.
On Sunday, September 19, 2010, Manuel Menal <mme...@hurdfr.org> wrote: > On 27/07/2010 17:39, Emilio Pozuelo Monfort wrote: >> Hi, > > Hello, > >> While adding support for SCM_RIGHTS to glibc, I've created a testcase that >> sends >> and receives some ports on the result of a socketpair() call. The ports sent >> were initially the two ports result of another socketpair() call, and it was >> working fine, but then I tried with the result of a couple of open() calls, >> and >> socket_recv() was returning EMIGSERVERDIED. > [snip] >> It's returning because of this: >> >> if (OutP->Head.msgh_id != 26115) { >> if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) >> return MIG_SERVER_DIED; >> >> But I'm not sure how to interpret it, and why a non-socket port in the ports >> argument would cause this. >> Any ideas? > > I think you've encountered a little bug in pflocal. > > Here's the story: the file descriptor you're sending is, in Mach terms, > a send right. It gets stored by pflocal (libpipe actually) when you send > it through socket_send() (see <pflocal/socket.c:S_socket_send>). When > you call socket_recv(), pflocal retrieves your send right and tries to > send it to the caller. But it sends it with the MACH_MSG_TYPE_MAKE_SEND > flag (see <pflocal/socket.c:S_socket_recv>). This can't work, since > MAKE_SEND only works with receive rights. So mach_msg() fails and you > get the error code you've mentioned. > > Here is a very simple fix for this bug: > > diff -Nurp hurd-20100829/pflocal/socket.c > hurd-20100829.patched//pflocal/socket.c > --- hurd-20100829/pflocal/socket.c 2010-09-19 12:49:09.000000000 +0200 > +++ hurd-20100829.patched//pflocal/socket.c 2010-09-19 > 12:47:23.000000000 +0200 > @@ -397,7 +397,7 @@ S_socket_recv (struct sock_user *user, > /* Setup mach ports for return. */ > { > *addr_type = MACH_MSG_TYPE_MAKE_SEND; > - *ports_type = MACH_MSG_TYPE_MAKE_SEND; > + *ports_type = MACH_MSG_TYPE_COPY_SEND; > if (source_addr) > { > *addr = ports_get_right (source_addr); > > I've tried several test cases (including yours) using your libc patch > for sendmsg()/recvmsg() and this fix for pflocal. They all work fine. > > As a sidenote, this also makes us able to use sshd with > UsePrivilegeSeparation set to yes (which used to fail because it sends > the tty fd through sendmsg() with SCM_RIGHTS, which fails silently > without your patch). > > HTH, > > -- > Manuel Menal > >