unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
blob 67de2e1829c84475d356675ff709be2b8a1f541d 7639 bytes (raw)
name: gnu/packages/patches/glibc-hurd-sendmsg-SCM_CREDS.patch 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
 
Subject: [PATCH] hurd: SCM_CREDS support

Adjusted for use in Guix by removing #include <sysdep-cancel.h>.


Svante Signell  <svante.signell@gmail.com>
Samuel Thibault  <samuel.thibault@ens-lyon.org>

	* sysdeps/mach/hurd/sendmsg.c (__libc_sendmsg): On SCM_CREDS
	control messages, record uids, pass a rendez-vous port in the
	control message, and call __auth_user_authenticate_request to
	make auth send credentials on that port.  Do not wait for a
	reply.
	* sysdeps/mach/hurd/recvmsg.c (contains_uid, contains_gid,
	check_auth): New functions.
	(__libc_recvmsg): On SCM_CREDS control messages, call check_auth
	to check the passed credentials thanks to the answer from the
	auth server.
	* hurd/Makefile (user-interfaces): Add auth_request and
	auth_reply.

---
 hurd/Makefile               |    2 
 sysdeps/mach/hurd/recvmsg.c |  137 ++++++++++++++++++++++++++++++++++++++++++++
 sysdeps/mach/hurd/sendmsg.c |   36 +++++++++++
 3 files changed, 174 insertions(+), 1 deletion(-)

--- a/sysdeps/mach/hurd/recvmsg.c
+++ b/sysdeps/mach/hurd/recvmsg.c
@@ -24,6 +24,123 @@
 #include <hurd/socket.h>
 #include <sysdep-cancel.h>
 
+static unsigned
+contains_uid (unsigned int n, __uid_t uids[n], __uid_t uid)
+{
+  unsigned i;
+
+  for (i = 0; i < n; i++)
+    if (uids[i] == uid)
+      return 1;
+  return 0;
+}
+
+static unsigned
+contains_gid (unsigned int n, __gid_t gids[n], __gid_t gid)
+{
+  unsigned i;
+
+  for (i = 0; i < n; i++)
+    if (gids[i] == gid)
+      return 1;
+  return 0;
+}
+
+/* Check the passed credentials.  */
+static error_t
+check_auth (mach_port_t rendezvous,
+		    __pid_t pid,
+		    __uid_t uid, __uid_t euid,
+		    __gid_t gid,
+		    int ngroups, __gid_t groups[ngroups])
+{
+  error_t err;
+  size_t neuids = CMGROUP_MAX, nauids = CMGROUP_MAX;
+  size_t negids = CMGROUP_MAX, nagids = CMGROUP_MAX;
+  __uid_t euids_buf[neuids], auids_buf[nauids];
+  __gid_t egids_buf[negids], agids_buf[nagids];
+  __uid_t *euids = euids_buf, *auids = auids_buf;
+  __gid_t *egids = egids_buf, *agids = agids_buf;
+
+  struct procinfo *pi = NULL;
+  mach_msg_type_number_t pi_size = 0;
+  int flags = PI_FETCH_TASKINFO;
+  char *tw = NULL;
+  size_t tw_size = 0;
+  unsigned i;
+
+  err = __mach_port_mod_refs (mach_task_self (), rendezvous,
+			    MACH_PORT_RIGHT_SEND, 1);
+  if (err)
+    goto out;
+
+  do
+    err = __USEPORT
+      (AUTH, __auth_server_authenticate (port,
+					 rendezvous, MACH_MSG_TYPE_COPY_SEND,
+					 MACH_PORT_NULL, 0,
+					 &euids, &neuids, &auids, &nauids,
+					 &egids, &negids, &agids, &nagids));
+  while (err == EINTR);
+  if (err)
+    goto out;
+
+  /* Check whether this process indeed has these IDs */
+  if (   !contains_uid (neuids, euids,  uid)
+      && !contains_uid (nauids, auids,  uid)
+   ||    !contains_uid (neuids, euids, euid)
+      && !contains_uid (nauids, auids, euid)
+   ||    !contains_gid (negids, egids,  gid)
+      && !contains_gid (nagids, agids,  gid)
+    )
+    {
+      err = EIO;
+      goto out;
+    }
+
+  /* Check groups */
+  for (i = 0; i < ngroups; i++)
+    if (   !contains_gid (negids, egids, groups[i])
+	&& !contains_gid (nagids, agids, groups[i]))
+      {
+	err = EIO;
+	goto out;
+      }
+
+  /* Check PID  */
+  /* XXX: Using proc_getprocinfo until
+     proc_user_authenticate proc_server_authenticate is implemented
+  */
+  /* Get procinfo to check the owner.  Maybe he faked the pid, but at least we
+     check the owner.  */
+  err = __USEPORT (PROC, __proc_getprocinfo (port, pid, &flags,
+					     (procinfo_t *)&pi,
+					     &pi_size, &tw, &tw_size));
+  if (err)
+    goto out;
+
+  if (   !contains_uid (neuids, euids, pi->owner)
+      && !contains_uid (nauids, auids, pi->owner))
+    err = EIO;
+
+out:
+  __mach_port_deallocate (__mach_task_self (), rendezvous);
+  if (euids != euids_buf)
+    __vm_deallocate (__mach_task_self(), (vm_address_t) euids, neuids * sizeof(uid_t));
+  if (auids != auids_buf)
+    __vm_deallocate (__mach_task_self(), (vm_address_t) auids, nauids * sizeof(uid_t));
+  if (egids != egids_buf)
+    __vm_deallocate (__mach_task_self(), (vm_address_t) egids, negids * sizeof(uid_t));
+  if (agids != agids_buf)
+    __vm_deallocate (__mach_task_self(), (vm_address_t) agids, nagids * sizeof(uid_t));
+  if (tw_size)
+    __vm_deallocate (__mach_task_self(), (vm_address_t) tw, tw_size);
+  if (pi_size)
+    __vm_deallocate (__mach_task_self(), (vm_address_t) pi, pi_size);
+
+  return err;
+}
+
 /* Receive a message as described by MESSAGE from socket FD.
    Returns the number of bytes read or -1 for errors.  */
 ssize_t
@@ -211,6 +328,21 @@
 	    newfds++;
 	  }
       }
+    else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDS)
+      {
+	/* SCM_CREDS support.  */
+	/* Check received credentials */
+	struct cmsgcred *ucredp = (struct cmsgcred *) CMSG_DATA(cmsg);
+
+	err = check_auth (ports[i],
+			  ucredp->cmcred_pid,
+			  ucredp->cmcred_uid, ucredp->cmcred_euid,
+			  ucredp->cmcred_gid,
+			  ucredp->cmcred_ngroups, ucredp->cmcred_groups);
+	if (err)
+	  goto cleanup;
+	i++;
+      }
   }
 
   for (i = 0; i < nports; i++)
@@ -241,6 +373,11 @@
 		__mach_port_deallocate (__mach_task_self (), ports[ii]);
 	      }
 	    }
+	  else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDS)
+	    {
+	      __mach_port_deallocate (__mach_task_self (), ports[ii]);
+	      ii++;
+	    }
 	}
     }
 
--- a/sysdeps/mach/hurd/sendmsg.c
+++ b/sysdeps/mach/hurd/sendmsg.c
@@ -19,10 +19,12 @@
 #include <string.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <unistd.h>
 
 #include <hurd.h>
 #include <hurd/fd.h>
 #include <hurd/ifsock.h>
 #include <hurd/socket.h>
+#include <hurd/auth_request.h>
 #include "hurd/hurdsocket.h"
 
@@ -113,6 +115,8 @@
     if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
       nports += (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
 		/ sizeof (int);
+    else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDS)
+      nports++;
 
   if (nports)
     ports = __alloca (nports * sizeof (mach_port_t));
@@ -147,6 +151,38 @@
 		goto out;
 	    }
 	}
+      else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDS)
+	{
+	  /* SCM_CREDS support: send credentials.   */
+	  mach_port_t rendezvous  = __mach_reply_port (), reply;
+	  struct cmsgcred *ucredp;
+
+	  err = __mach_port_insert_right (mach_task_self (), rendezvous,
+					  rendezvous, MACH_MSG_TYPE_MAKE_SEND);
+	  ports[nports++] = rendezvous;
+	  if (err)
+	    goto out;
+
+	  ucredp = (struct cmsgcred *) CMSG_DATA(cmsg);
+	  /* Fill in credentials data */
+	  ucredp->cmcred_pid = __getpid();
+	  ucredp->cmcred_uid = __getuid();
+	  ucredp->cmcred_euid = __geteuid();
+	  ucredp->cmcred_gid = __getgid();
+	  ucredp->cmcred_ngroups =
+	    __getgroups (sizeof (ucredp->cmcred_groups) / sizeof (gid_t),
+			 ucredp->cmcred_groups);
+
+	  /* And make auth server authenticate us.  */
+	  reply = __mach_reply_port();
+	  err = __USEPORT
+	    (AUTH, __auth_user_authenticate_request (port,
+					reply, MACH_MSG_TYPE_MAKE_SEND_ONCE,
+					rendezvous, MACH_MSG_TYPE_MAKE_SEND));
+	  __mach_port_deallocate (__mach_task_self (), reply);
+	  if (err)
+	    goto out;
+	}
     }
 
   if (addr)
--- a/hurd/Makefile
+++ b/hurd/Makefile
@@ -29,7 +29,7 @@
 # The RPC interfaces go in a separate library.
 interface-library := libhurduser
 user-interfaces		:= $(addprefix hurd/,\
-				       auth startup \
+				       auth auth_request auth_reply startup \
 				       process process_request \
 				       msg msg_reply msg_request \
 				       exec exec_startup crash interrupt \

debug log:

solving 67de2e1829 ...
found 67de2e1829 in https://yhetil.org/guix-patches/727b3d7ec511589ab714874d6648ee4afa458e3c.camel@telenet.be/

applying [1/1] https://yhetil.org/guix-patches/727b3d7ec511589ab714874d6648ee4afa458e3c.camel@telenet.be/
diff --git a/gnu/packages/patches/glibc-hurd-sendmsg-SCM_CREDS.patch b/gnu/packages/patches/glibc-hurd-sendmsg-SCM_CREDS.patch
new file mode 100644
index 0000000000..67de2e1829

1:29: trailing whitespace.
 hurd/Makefile               |    2 
1:39: trailing whitespace.
 
1:161: space before tab in indent.
 	    newfds++;
1:162: space before tab in indent.
 	  }
1:180: trailing whitespace.
 
Checking patch gnu/packages/patches/glibc-hurd-sendmsg-SCM_CREDS.patch...
Applied patch gnu/packages/patches/glibc-hurd-sendmsg-SCM_CREDS.patch cleanly.
warning: squelched 16 whitespace errors
warning: 21 lines add whitespace errors.

index at:
100644 67de2e1829c84475d356675ff709be2b8a1f541d	gnu/packages/patches/glibc-hurd-sendmsg-SCM_CREDS.patch

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).