~ubuntu-branches/ubuntu/precise/eglibc/precise

« back to all changes in this revision

Viewing changes to debian/patches/hurd-i386/unsubmitted-sendmsg-SCM_RIGHTS.diff

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2011-10-04 17:48:26 UTC
  • mfrom: (216.1.23 oneiric)
  • Revision ID: package-import@ubuntu.com-20111004174826-2cyb9ewn3ucymlsx
Tags: 2.13-20ubuntu5
libc6-dev: Don't break the current {gnat,gcj}-4.4-base versons. LP: #853688.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
5
 
 
6
---
 
7
 sysdeps/mach/hurd/recvmsg.c |  108 ++++++++++++++++++++++++++++++++++++++++++--
 
8
 sysdeps/mach/hurd/sendmsg.c |   73 ++++++++++++++++++++++++-----
 
9
 2 files changed, 166 insertions(+), 15 deletions(-)
 
10
 
 
11
--- a/sysdeps/mach/hurd/recvmsg.c
 
12
+++ b/sysdeps/mach/hurd/recvmsg.c
 
13
@@ -1,4 +1,4 @@
 
14
-/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 
15
+/* Copyright (C) 2001, 2002, 2010 Free Software Foundation, Inc.
 
16
    This file is part of the GNU C Library.
 
17
 
 
18
    The GNU C Library is free software; you can redistribute it and/or
 
19
@@ -33,13 +33,33 @@
 
20
   addr_port_t aport;
 
21
   char *data = NULL;
 
22
   mach_msg_type_number_t len = 0;
 
23
-  mach_port_t *ports;
 
24
+  mach_port_t *ports, *newports;
 
25
   mach_msg_type_number_t nports = 0;
 
26
+  struct cmsghdr *cmsg;
 
27
   char *cdata = NULL;
 
28
   mach_msg_type_number_t clen = 0;
 
29
   size_t amount;
 
30
   char *buf;
 
31
-  int i;
 
32
+  int nfds, *fds;
 
33
+  int i, j;
 
34
+
 
35
+  error_t reauthenticate (mach_port_t port, mach_port_t *result)
 
36
+    {
 
37
+      error_t err;
 
38
+      mach_port_t ref;
 
39
+      ref = __mach_reply_port ();
 
40
+      do
 
41
+       err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
 
42
+      while (err == EINTR);
 
43
+      if (!err)
 
44
+       do
 
45
+         err = __USEPORT (AUTH, __auth_user_authenticate (port,
 
46
+                                         ref, MACH_MSG_TYPE_MAKE_SEND,
 
47
+                                         result));
 
48
+       while (err == EINTR);
 
49
+      __mach_port_destroy (__mach_task_self (), ref);
 
50
+      return err;
 
51
+    }
 
52
 
 
53
   /* Find the total number of bytes to be read.  */
 
54
   amount = 0;
 
55
@@ -136,6 +156,85 @@
 
56
     message->msg_controllen = clen;
 
57
   memcpy (message->msg_control, cdata, message->msg_controllen);
 
58
 
 
59
+  /* SCM_RIGHTS ports.  */
 
60
+  if (nports > 0)
 
61
+    {
 
62
+      newports = __alloca (nports * sizeof (mach_port_t));
 
63
+
 
64
+      /* Reauthenticate all ports here.  */
 
65
+      for (i = 0; i < nports; i++)
 
66
+       {
 
67
+         err = reauthenticate (ports[i], &newports[i]);
 
68
+         __mach_port_deallocate (__mach_task_self (), ports[i]);
 
69
+         if (err)
 
70
+           {
 
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]);
 
75
+
 
76
+             __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
 
77
+             __hurd_fail (err);
 
78
+           }
 
79
+       }
 
80
+
 
81
+      j = 0;
 
82
+      for (cmsg = CMSG_FIRSTHDR (message);
 
83
+          cmsg;
 
84
+          cmsg = CMSG_NXTHDR (message, cmsg))
 
85
+       {
 
86
+         if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
 
87
+           {
 
88
+             fds = (int *) CMSG_DATA (cmsg);
 
89
+             nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
 
90
+                    / sizeof (int);
 
91
+
 
92
+             for (i = 0; i < nfds && j < nports; i++)
 
93
+               {
 
94
+                 /* The fd's flags are passed in the control data.  */
 
95
+                 fds[i] = _hurd_intern_fd (newports[j++], fds[i], 0);
 
96
+                 if (fds[i] == -1)
 
97
+                   {
 
98
+                     err = errno;
 
99
+                     goto cleanup;
 
100
+                   }
 
101
+               }
 
102
+           }
 
103
+       }
 
104
+
 
105
+      if (j != nports)
 
106
+       err = EGRATUITOUS;
 
107
+
 
108
+      if (err)
 
109
+      cleanup:
 
110
+       {
 
111
+         /* Clean up all the file descriptors.  */
 
112
+         nports = j;
 
113
+         j = 0;
 
114
+         for (cmsg = CMSG_FIRSTHDR (message);
 
115
+              cmsg;
 
116
+              cmsg = CMSG_NXTHDR (message, cmsg))
 
117
+           {
 
118
+             if (cmsg->cmsg_level == SOL_SOCKET
 
119
+                 && cmsg->cmsg_type == SCM_RIGHTS)
 
120
+               {
 
121
+                 fds = (int *) CMSG_DATA (cmsg);
 
122
+                 nfds = (cmsg->cmsg_len
 
123
+                         - CMSG_ALIGN (sizeof (struct cmsghdr)))
 
124
+                        / sizeof (int);
 
125
+                 for (i = 0; i < nfds && j < nports; i++, j++)
 
126
+                   _hurd_fd_close (_hurd_fd_get (fds[i]));
 
127
+               }
 
128
+           }
 
129
+
 
130
+         for (; j < nports; j++)
 
131
+           __mach_port_deallocate (__mach_task_self (), newports[j]);
 
132
+
 
133
+         __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
 
134
+         __hurd_fail (err);
 
135
+       }
 
136
+    }
 
137
+
 
138
   __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
 
139
 
 
140
   return (buf - data);
 
141
--- a/sysdeps/mach/hurd/sendmsg.c
 
142
+++ b/sysdeps/mach/hurd/sendmsg.c
 
143
@@ -1,4 +1,4 @@
 
144
-/* Copyright (C) 2001,2002,2004 Free Software Foundation, Inc.
 
145
+/* Copyright (C) 2001,2002,2004,2010 Free Software Foundation, Inc.
 
146
    This file is part of the GNU C Library.
 
147
 
 
148
    The GNU C Library is free software; you can redistribute it and/or
 
149
@@ -32,6 +32,10 @@
 
150
 __libc_sendmsg (int fd, const struct msghdr *message, int flags)
 
151
 {
 
152
   error_t err = 0;
 
153
+  struct cmsghdr *cmsg;
 
154
+  mach_port_t *ports = NULL;
 
155
+  mach_msg_type_number_t nports = 0;
 
156
+  int *fds, nfds;
 
157
   struct sockaddr_un *addr = message->msg_name;
 
158
   socklen_t addr_len = message->msg_namelen;
 
159
   addr_port_t aport = MACH_PORT_NULL;
 
160
@@ -44,6 +48,7 @@
 
161
   mach_msg_type_number_t len;
 
162
   mach_msg_type_number_t amount;
 
163
   int dealloc = 0;
 
164
+  int socketrpc = 0;
 
165
   int i;
 
166
 
 
167
   /* Find the total number of bytes to be written.  */
 
168
@@ -101,6 +106,46 @@
 
169
        }
 
170
     }
 
171
 
 
172
+  /* SCM_RIGHTS support: get the number of fds to send.  */
 
173
+  cmsg = CMSG_FIRSTHDR (message);
 
174
+  for (; cmsg; cmsg = CMSG_NXTHDR (message, cmsg))
 
175
+    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
 
176
+      nports += (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
 
177
+               / sizeof (int);
 
178
+
 
179
+  if (nports)
 
180
+    ports = __alloca (nports * sizeof (mach_port_t));
 
181
+
 
182
+  nports = 0;
 
183
+  for (cmsg = CMSG_FIRSTHDR (message);
 
184
+       cmsg;
 
185
+       cmsg = CMSG_NXTHDR (message, cmsg))
 
186
+    {
 
187
+      if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
 
188
+       {
 
189
+         fds = (int *) CMSG_DATA (cmsg);
 
190
+         nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
 
191
+                / sizeof (int);
 
192
+
 
193
+         for (i = 0; i < nfds; i++)
 
194
+           {
 
195
+             err = HURD_DPORT_USE
 
196
+               (fds[i],
 
197
+                ({
 
198
+                  err = __io_restrict_auth (port, &ports[nports],
 
199
+                                            0, 0, 0, 0);
 
200
+                  if (! err)
 
201
+                    nports++;
 
202
+                  /* We pass the flags in the control data.  */
 
203
+                  fds[i] = descriptor->flags;
 
204
+                }));
 
205
+
 
206
+             if (err)
 
207
+               goto out;
 
208
+           }
 
209
+       }
 
210
+    }
 
211
+
 
212
   if (addr)
 
213
     {
 
214
       if (addr->sun_family == AF_LOCAL)
 
215
@@ -110,9 +155,8 @@
 
216
          file_t file = __file_name_lookup (addr->sun_path, 0, 0);
 
217
          if (file == MACH_PORT_NULL)
 
218
            {
 
219
-             if (dealloc)
 
220
-               __vm_deallocate (__mach_task_self (), data.addr, len);
 
221
-             return -1;
 
222
+             err = errno;
 
223
+             goto out;
 
224
            }
 
225
          err = __ifsock_getsockaddr (file, &aport);
 
226
          __mach_port_deallocate (__mach_task_self (), file);
 
227
@@ -120,11 +164,7 @@
 
228
            /* The file did not grok the ifsock protocol.  */
 
229
            err = ENOTSOCK;
 
230
          if (err)
 
231
-           {
 
232
-             if (dealloc)
 
233
-               __vm_deallocate (__mach_task_self (), data.addr, len);
 
234
-             return __hurd_fail (err);
 
235
-           }
 
236
+           goto out;
 
237
        }
 
238
       else
 
239
        err = EIEIO;
 
240
@@ -143,8 +183,9 @@
 
241
                              /* Send the data.  */
 
242
                              err = __socket_send (port, aport,
 
243
                                                   flags, data.ptr, len,
 
244
-                                                  NULL,
 
245
-                                                  MACH_MSG_TYPE_COPY_SEND, 0,
 
246
+                                                  ports,
 
247
+                                                  MACH_MSG_TYPE_COPY_SEND,
 
248
+                                                  nports,
 
249
                                                   message->msg_control,
 
250
                                                   message->msg_controllen,
 
251
                                                   &amount);
 
252
@@ -153,11 +194,19 @@
 
253
                            }
 
254
                          err;
 
255
                        }));
 
256
+  socketrpc = 1;
 
257
+
 
258
+ out:
 
259
+  for (i = 0; i < nports; i++)
 
260
+    __mach_port_deallocate (__mach_task_self (), ports[i]);
 
261
 
 
262
   if (dealloc)
 
263
     __vm_deallocate (__mach_task_self (), data.addr, len);
 
264
 
 
265
-  return err ? __hurd_sockfail (fd, flags, err) : amount;
 
266
+  if (socketrpc)
 
267
+    return err ? __hurd_sockfail (fd, flags, err) : amount;
 
268
+  else
 
269
+    return __hurd_fail (err);
 
270
 }
 
271
 
 
272
 weak_alias (__libc_sendmsg, sendmsg)