[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: socket_send & socket_recv fail when sending non-socket ports
From: |
Manuel Menal |
Subject: |
Re: socket_send & socket_recv fail when sending non-socket ports |
Date: |
Sun, 19 Sep 2010 13:54:23 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.12) Gecko/20100918 Icedove/3.0.8 |
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
- Re: socket_send & socket_recv fail when sending non-socket ports,
Manuel Menal <=