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