1 From 1b911148009f696717da0b676d6d10af85d5aefb Mon Sep 17 00:00:00 2001
2 From: Emilio Pozuelo Monfort <pochu27@gmail.com>
3 Date: Sat, 17 Jul 2010 22:09:13 +0200
4 Subject: [PATCH] Add support to send file descriptors over Unix sockets
6 diff --git a/sysdeps/mach/hurd/recvmsg.c b/sysdeps/mach/hurd/recvmsg.c
7 index 33897b8..0935c79 100644
8 --- a/sysdeps/mach/hurd/recvmsg.c
9 +++ b/sysdeps/mach/hurd/recvmsg.c
11 -/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
12 +/* Copyright (C) 2001, 2002, 2010 Free Software Foundation, Inc.
13 This file is part of the GNU C Library.
15 The GNU C Library is free software; you can redistribute it and/or
16 @@ -33,13 +33,35 @@ __libc_recvmsg (int fd, struct msghdr *message, int flags)
19 mach_msg_type_number_t len = 0;
21 + mach_port_t *ports, *newports;
22 mach_msg_type_number_t nports = 0;
23 + struct cmsghdr *cmsg;
25 mach_msg_type_number_t clen = 0;
34 + error_t reauthenticate (mach_port_t port, mach_port_t *result)
38 + ref = __mach_reply_port ();
40 + err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
41 + while (err == EINTR);
44 + err = __auth_user_authenticate (auth,
45 + ref, MACH_MSG_TYPE_MAKE_SEND,
47 + while (err == EINTR);
48 + __mach_port_destroy (__mach_task_self (), ref);
52 /* Find the total number of bytes to be read. */
54 @@ -136,6 +158,86 @@ __libc_recvmsg (int fd, struct msghdr *message, int flags)
55 message->msg_controllen = clen;
56 memcpy (message->msg_control, cdata, message->msg_controllen);
58 + /* SCM_RIGHTS ports. */
62 + newports = __alloca (nports * sizeof (mach_port_t));
64 + /* Reauthenticate all ports here. */
65 + for (i = 0; i < nports; i++)
67 + err = reauthenticate (ports[i], &newports[i]);
68 + __mach_port_deallocate (__mach_task_self (), ports[i]);
71 + for (j = 0; j < i; j++)
72 + __mach_port_deallocate (__mach_task_self (), newports[j]);
73 + for (j = i+1; j < nports; j++)
74 + __mach_port_deallocate (__mach_task_self (), ports[j]);
76 + __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
82 + for (cmsg = CMSG_FIRSTHDR (message);
84 + cmsg = CMSG_NXTHDR (message, cmsg))
86 + if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
88 + fds = (int *) CMSG_DATA (cmsg);
89 + nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
92 + for (i = 0; i < nfds && j < nports; i++)
94 + /* The fd's flags are passed in the control data. */
95 + fds[i] = _hurd_intern_fd (newports[j++], fds[i], 0);
111 + /* Clean up all the file descriptors. */
114 + for (cmsg = CMSG_FIRSTHDR (message);
116 + cmsg = CMSG_NXTHDR (message, cmsg))
118 + if (cmsg->cmsg_level == SOL_SOCKET
119 + && cmsg->cmsg_type == SCM_RIGHTS)
121 + fds = (int *) CMSG_DATA (cmsg);
122 + nfds = (cmsg->cmsg_len
123 + - CMSG_ALIGN (sizeof (struct cmsghdr)))
125 + for (i = 0; i < nfds && j < nports; i++, j++)
126 + _hurd_fd_close (_hurd_fd_get (fds[i]));
130 + for (; j < nports; j++)
131 + __mach_port_deallocate (__mach_task_self (), newports[j]);
133 + __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
138 __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
141 diff --git a/sysdeps/mach/hurd/sendmsg.c b/sysdeps/mach/hurd/sendmsg.c
142 index 118fd59..fb8dd2d 100644
143 --- a/sysdeps/mach/hurd/sendmsg.c
144 +++ b/sysdeps/mach/hurd/sendmsg.c
146 -/* Copyright (C) 2001,2002,2004 Free Software Foundation, Inc.
147 +/* Copyright (C) 2001,2002,2004,2010 Free Software Foundation, Inc.
148 This file is part of the GNU C Library.
150 The GNU C Library is free software; you can redistribute it and/or
151 @@ -32,6 +32,10 @@ ssize_t
152 __libc_sendmsg (int fd, const struct msghdr *message, int flags)
155 + struct cmsghdr *cmsg;
156 + mach_port_t *ports = NULL;
157 + mach_msg_type_number_t nports = 0;
159 struct sockaddr_un *addr = message->msg_name;
160 socklen_t addr_len = message->msg_namelen;
161 addr_port_t aport = MACH_PORT_NULL;
162 @@ -44,6 +48,7 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags)
163 mach_msg_type_number_t len;
164 mach_msg_type_number_t amount;
169 /* Find the total number of bytes to be written. */
170 @@ -101,6 +106,46 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags)
174 + /* SCM_RIGHTS support: get the number of fds to send. */
175 + cmsg = CMSG_FIRSTHDR (message);
176 + for (; cmsg; cmsg = CMSG_NXTHDR (message, cmsg))
177 + if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
178 + nports += (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
182 + ports = __alloca (nports * sizeof (mach_port_t));
185 + for (cmsg = CMSG_FIRSTHDR (message);
187 + cmsg = CMSG_NXTHDR (message, cmsg))
189 + if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
191 + fds = (int *) CMSG_DATA (cmsg);
192 + nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
195 + for (i = 0; i < nfds; i++)
197 + err = HURD_DPORT_USE
200 + err = __io_restrict_auth (port, &ports[nports],
204 + /* We pass the flags in the control data. */
205 + fds[i] = descriptor->flags;
216 if (addr->sun_family == AF_LOCAL)
217 @@ -110,9 +155,8 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags)
218 file_t file = __file_name_lookup (addr->sun_path, 0, 0);
219 if (file == MACH_PORT_NULL)
222 - __vm_deallocate (__mach_task_self (), data.addr, len);
227 err = __ifsock_getsockaddr (file, &aport);
228 __mach_port_deallocate (__mach_task_self (), file);
229 @@ -120,11 +164,7 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags)
230 /* The file did not grok the ifsock protocol. */
235 - __vm_deallocate (__mach_task_self (), data.addr, len);
236 - return __hurd_fail (err);
242 @@ -143,8 +183,9 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags)
244 err = __socket_send (port, aport,
245 flags, data.ptr, len,
247 - MACH_MSG_TYPE_COPY_SEND, 0,
249 + MACH_MSG_TYPE_COPY_SEND,
251 message->msg_control,
252 message->msg_controllen,
254 @@ -153,11 +194,19 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags)
261 + for (i = 0; i < nports; i++)
262 + __mach_port_deallocate (__mach_task_self (), ports[i]);
265 __vm_deallocate (__mach_task_self (), data.addr, len);
267 - return err ? __hurd_sockfail (fd, flags, err) : amount;
269 + return err ? __hurd_sockfail (fd, flags, err) : amount;
271 + return __hurd_fail (err);
274 weak_alias (__libc_sendmsg, sendmsg)