[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

r6604 - in glibc-package/branches/glibc-2.21/debian: . patches patches/hurd-i386



Author: sthibault
Date: 2015-09-20 21:09:56 +0000 (Sun, 20 Sep 2015)
New Revision: 6604

Added:
   glibc-package/branches/glibc-2.21/debian/patches/hurd-i386/tg-sendmsg-SCM_CREDS.diff
Modified:
   glibc-package/branches/glibc-2.21/debian/changelog
   glibc-package/branches/glibc-2.21/debian/patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff
   glibc-package/branches/glibc-2.21/debian/patches/series
Log:
port r6602 from trunk: 
* hurd-i386/tg-sendmsg-SCM_RIGHTS.diff: Update from upstream.
* hurd-i386/tg-sendmsg-SCM_CREDS.diff: New patch, adds support for
  passing credentials over sockets (SCM_CREDS).


Modified: glibc-package/branches/glibc-2.21/debian/changelog
===================================================================
--- glibc-package/branches/glibc-2.21/debian/changelog	2015-09-20 21:09:51 UTC (rev 6603)
+++ glibc-package/branches/glibc-2.21/debian/changelog	2015-09-20 21:09:56 UTC (rev 6604)
@@ -315,6 +315,9 @@
     build with newer mig.
   * patches/hurd-i386/cvs-cache-mach_host_self.diff: New patch to avoid port
     count issue on the host port.
+  * patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff: Update from upstream.
+  * patches/hurd-i386/tg-sendmsg-SCM_CREDS.diff: New patch, adds support for
+    passing credentials over sockets (SCM_CREDS).
 
  -- Samuel Thibault <sthibault@debian.org>  Sun, 13 Sep 2015 19:50:50 +0200
 

Copied: glibc-package/branches/glibc-2.21/debian/patches/hurd-i386/tg-sendmsg-SCM_CREDS.diff (from rev 6602, glibc-package/trunk/debian/patches/hurd-i386/tg-sendmsg-SCM_CREDS.diff)
===================================================================
--- glibc-package/branches/glibc-2.21/debian/patches/hurd-i386/tg-sendmsg-SCM_CREDS.diff	                        (rev 0)
+++ glibc-package/branches/glibc-2.21/debian/patches/hurd-i386/tg-sendmsg-SCM_CREDS.diff	2015-09-20 21:09:56 UTC (rev 6604)
@@ -0,0 +1,242 @@
+Subject: [PATCH] hurd: SCM_CREDS support
+
+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.
+
+---
+ sysdeps/mach/hurd/recvmsg.c | 136 ++++++++++++++++++++++++++++++++++++++++++++
+ sysdeps/mach/hurd/sendmsg.c |  34 +++++++++++
+ 2 files changed, 170 insertions(+)
+
+--- a/sysdeps/mach/hurd/recvmsg.c
++++ b/sysdeps/mach/hurd/recvmsg.c
+@@ -23,6 +23,123 @@
+ #include <hurd/fd.h>
+ #include <hurd/socket.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
+@@ -191,6 +308,21 @@ __libc_recvmsg (int fd, struct msghdr *m
+ 	    i++;
+ 	  }
+       }
++    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++)
+@@ -221,6 +353,10 @@ cleanup:
+ 		__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]);
++	    }
+ 	}
+     }
+ 
+--- a/sysdeps/mach/hurd/sendmsg.c
++++ b/sysdeps/mach/hurd/sendmsg.c
+@@ -111,6 +111,8 @@ __libc_sendmsg (int fd, const struct msg
+     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));
+@@ -145,6 +147,38 @@ __libc_sendmsg (int fd, const struct msg
+ 		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 @@ inline-headers = hurd.h $(addprefix hurd
+ # 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 \

Modified: glibc-package/branches/glibc-2.21/debian/patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff
===================================================================
--- glibc-package/branches/glibc-2.21/debian/patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff	2015-09-20 21:09:51 UTC (rev 6603)
+++ glibc-package/branches/glibc-2.21/debian/patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff	2015-09-20 21:09:56 UTC (rev 6604)
@@ -4,18 +4,18 @@
 Subject: [PATCH] Add support to send file descriptors over Unix sockets
 
 ---
- sysdeps/mach/hurd/recvmsg.c |  105 ++++++++++++++++++++++++++++++++++++++++++--
- sysdeps/mach/hurd/sendmsg.c |   73 +++++++++++++++++++++++++-----
- 2 files changed, 163 insertions(+), 15 deletions(-)
+ sysdeps/mach/hurd/recvmsg.c | 92 ++++++++++++++++++++++++++++++++++++++++++++-
+ sysdeps/mach/hurd/sendmsg.c | 73 +++++++++++++++++++++++++++++------
+ 2 files changed, 152 insertions(+), 13 deletions(-)
 
 --- a/sysdeps/mach/hurd/recvmsg.c
 +++ b/sysdeps/mach/hurd/recvmsg.c
-@@ -32,13 +32,33 @@
+@@ -32,13 +32,33 @@ __libc_recvmsg (int fd, struct msghdr *m
    addr_port_t aport;
    char *data = NULL;
    mach_msg_type_number_t len = 0;
 -  mach_port_t *ports;
-+  mach_port_t *ports, *newports;
++  mach_port_t *ports, *newports = NULL;
    mach_msg_type_number_t nports = 0;
 +  struct cmsghdr *cmsg;
    char *cdata = NULL;
@@ -23,8 +23,8 @@
    size_t amount;
    char *buf;
 -  int i;
-+  int nfds, *fds;
-+  int i, j;
++  int nfds, *opened_fds = NULL;
++  int i, ii, j;
 +
 +  error_t reauthenticate (mach_port_t port, mach_port_t *result)
 +    {
@@ -46,32 +46,60 @@
  
    /* Find the total number of bytes to be read.  */
    amount = 0;
-@@ -135,6 +155,85 @@
+@@ -135,9 +155,77 @@ __libc_recvmsg (int fd, struct msghdr *m
      message->msg_controllen = clen;
    memcpy (message->msg_control, cdata, message->msg_controllen);
  
-+  /* SCM_RIGHTS ports.  */
 +  if (nports > 0)
 +    {
 +      newports = __alloca (nports * sizeof (mach_port_t));
++      opened_fds = __alloca (nports * sizeof (int));
++    }
 +
-+      /* Reauthenticate all ports here.  */
-+      for (i = 0; i < nports; i++)
-+	{
-+	  err = reauthenticate (ports[i], &newports[i]);
-+	  __mach_port_deallocate (__mach_task_self (), ports[i]);
-+	  if (err)
-+	    {
-+	      for (j = 0; j < i; j++)
-+		__mach_port_deallocate (__mach_task_self (), newports[j]);
-+	      for (j = i+1; j < nports; j++)
-+		__mach_port_deallocate (__mach_task_self (), ports[j]);
++  /* This counts how many ports we processed completely.  */
++  i = 0;
 +
-+	      __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
-+	      __hurd_fail (err);
-+	    }
-+	}
++  for (cmsg = CMSG_FIRSTHDR (message);
++       cmsg;
++       cmsg = CMSG_NXTHDR (message, cmsg))
++  {
++    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
++      {
++	/* SCM_RIGHTS support.  */
++	/* The fd's flags are passed in the control data.  */
++	int *fds = (int *) CMSG_DATA (cmsg);
++	nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
++	       / sizeof (int);
 +
++	for (j = 0; j < nfds; j++)
++	  {
++	    err = reauthenticate (ports[i], &newports[i]);
++	    if (err)
++	      goto cleanup;
++	    fds[j] = opened_fds[i] = _hurd_intern_fd (newports[i], fds[j], 0);
++	    if (fds[j] == -1)
++	      {
++		err = errno;
++		__mach_port_deallocate (__mach_task_self (), newports[i]);
++		goto cleanup;
++	      }
++	    i++;
++	  }
++      }
++  }
++
++  for (i = 0; i < nports; i++)
++    __mach_port_deallocate (mach_task_self (), ports[i]);
++
+   __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
+ 
+   return (buf - data);
++
++cleanup:
++  /* Clean up all the file descriptors from port 0 to i-1.  */
++  if (nports > 0)
++    {
++      ii = 0;
 +      j = 0;
 +      for (cmsg = CMSG_FIRSTHDR (message);
 +	   cmsg;
@@ -79,62 +107,26 @@
 +	{
 +	  if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
 +	    {
-+	      fds = (int *) CMSG_DATA (cmsg);
 +	      nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
 +		     / sizeof (int);
-+
-+	      for (i = 0; i < nfds && j < nports; i++)
-+		{
-+		  /* The fd's flags are passed in the control data.  */
-+		  fds[i] = _hurd_intern_fd (newports[j++], fds[i], 0);
-+		  if (fds[i] == -1)
-+		    {
-+		      err = errno;
-+		      goto cleanup;
-+		    }
-+		}
++	      for (j = 0; j < nfds && ii < i; j++, ii++)
++	      {
++		_hurd_fd_close (_hurd_fd_get (opened_fds[ii]));
++		__mach_port_deallocate (__mach_task_self (), newports[ii]);
++		__mach_port_deallocate (__mach_task_self (), ports[ii]);
++	      }
 +	    }
 +	}
-+
-+      if (j != nports)
-+	err = EGRATUITOUS;
-+
-+      if (err)
-+      cleanup:
-+	{
-+	  /* Clean up all the file descriptors.  */
-+	  nports = j;
-+	  j = 0;
-+	  for (cmsg = CMSG_FIRSTHDR (message);
-+	       cmsg;
-+	       cmsg = CMSG_NXTHDR (message, cmsg))
-+	    {
-+	      if (cmsg->cmsg_level == SOL_SOCKET
-+		  && cmsg->cmsg_type == SCM_RIGHTS)
-+		{
-+		  fds = (int *) CMSG_DATA (cmsg);
-+		  nfds = (cmsg->cmsg_len
-+			  - CMSG_ALIGN (sizeof (struct cmsghdr)))
-+			 / sizeof (int);
-+		  for (i = 0; i < nfds && j < nports; i++, j++)
-+		    _hurd_fd_close (_hurd_fd_get (fds[i]));
-+		}
-+	    }
-+
-+	  for (; j < nports; j++)
-+	    __mach_port_deallocate (__mach_task_self (), newports[j]);
-+
-+	  __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
-+	  __hurd_fail (err);
-+	}
 +    }
 +
-   __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
++  __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
++  return __hurd_fail (err);
+ }
  
-   return (buf - data);
+ weak_alias (__libc_recvmsg, recvmsg)
 --- a/sysdeps/mach/hurd/sendmsg.c
 +++ b/sysdeps/mach/hurd/sendmsg.c
-@@ -31,6 +31,10 @@
+@@ -31,6 +31,10 @@ ssize_t
  __libc_sendmsg (int fd, const struct msghdr *message, int flags)
  {
    error_t err = 0;
@@ -145,7 +137,7 @@
    struct sockaddr_un *addr = message->msg_name;
    socklen_t addr_len = message->msg_namelen;
    addr_port_t aport = MACH_PORT_NULL;
-@@ -43,6 +47,7 @@
+@@ -43,6 +47,7 @@ __libc_sendmsg (int fd, const struct msg
    mach_msg_type_number_t len;
    mach_msg_type_number_t amount;
    int dealloc = 0;
@@ -153,11 +145,11 @@
    int i;
  
    /* Find the total number of bytes to be written.  */
-@@ -100,6 +105,47 @@
+@@ -100,6 +105,48 @@ __libc_sendmsg (int fd, const struct msg
  	}
      }
  
-+  /* SCM_RIGHTS support: get the number of fds to send.  */
++  /* Allocate enough room for ports.  */
 +  cmsg = CMSG_FIRSTHDR (message);
 +  for (; cmsg; cmsg = CMSG_NXTHDR (message, cmsg))
 +    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
@@ -174,6 +166,7 @@
 +    {
 +      if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
 +	{
++	  /* SCM_RIGHTS support: send FDs.   */
 +	  fds = (int *) CMSG_DATA (cmsg);
 +	  nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
 +		 / sizeof (int);
@@ -201,7 +194,7 @@
    if (addr)
      {
        if (addr->sun_family == AF_LOCAL)
-@@ -109,9 +154,8 @@
+@@ -109,9 +156,8 @@ __libc_sendmsg (int fd, const struct msg
  	  file_t file = __file_name_lookup (addr->sun_path, 0, 0);
  	  if (file == MACH_PORT_NULL)
  	    {
@@ -213,7 +206,7 @@
  	    }
  	  err = __ifsock_getsockaddr (file, &aport);
  	  __mach_port_deallocate (__mach_task_self (), file);
-@@ -119,11 +163,7 @@
+@@ -119,11 +165,7 @@ __libc_sendmsg (int fd, const struct msg
  	    /* The file did not grok the ifsock protocol.  */
  	    err = ENOTSOCK;
  	  if (err)
@@ -226,7 +219,7 @@
  	}
        else
  	err = EIEIO;
-@@ -142,8 +182,9 @@
+@@ -142,8 +184,9 @@ __libc_sendmsg (int fd, const struct msg
  			      /* Send the data.  */
  			      err = __socket_send (port, aport,
  						   flags, data.ptr, len,
@@ -238,7 +231,7 @@
  						   message->msg_control,
  						   message->msg_controllen,
  						   &amount);
-@@ -152,11 +193,19 @@
+@@ -152,11 +195,19 @@ __libc_sendmsg (int fd, const struct msg
  			    }
  			  err;
  			}));

Modified: glibc-package/branches/glibc-2.21/debian/patches/series
===================================================================
--- glibc-package/branches/glibc-2.21/debian/patches/series	2015-09-20 21:09:51 UTC (rev 6603)
+++ glibc-package/branches/glibc-2.21/debian/patches/series	2015-09-20 21:09:56 UTC (rev 6604)
@@ -84,6 +84,7 @@
 hurd-i386/tg-locarchive.diff
 hurd-i386/tg-no-hp-timing.diff
 hurd-i386/tg-sendmsg-SCM_RIGHTS.diff
+hurd-i386/tg-sendmsg-SCM_CREDS.diff
 hurd-i386/tg-grantpt.diff
 hurd-i386/submitted-add-needed.diff
 hurd-i386/local-ED.diff


Reply to: