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

Added:
   
glibc-package/branches/glibc-2.22/debian/patches/hurd-i386/tg-sendmsg-SCM_CREDS.diff
Modified:
   glibc-package/branches/glibc-2.22/debian/changelog
   
glibc-package/branches/glibc-2.22/debian/patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff
   glibc-package/branches/glibc-2.22/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.22/debian/changelog
===================================================================
--- glibc-package/branches/glibc-2.22/debian/changelog  2015-09-20 21:05:05 UTC 
(rev 6602)
+++ glibc-package/branches/glibc-2.22/debian/changelog  2015-09-20 21:09:51 UTC 
(rev 6603)
@@ -382,6 +382,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 <sthiba...@debian.org>  Sun, 13 Sep 2015 19:50:50 +0200
 

Copied: 
glibc-package/branches/glibc-2.22/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.22/debian/patches/hurd-i386/tg-sendmsg-SCM_CREDS.diff
                                (rev 0)
+++ 
glibc-package/branches/glibc-2.22/debian/patches/hurd-i386/tg-sendmsg-SCM_CREDS.diff
        2015-09-20 21:09:51 UTC (rev 6603)
@@ -0,0 +1,242 @@
+Subject: [PATCH] hurd: SCM_CREDS support
+
+Svante Signell  <svante.sign...@gmail.com>
+Samuel Thibault  <samuel.thiba...@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
+@@ -112,6 +112,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));
+@@ -146,6 +148,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.22/debian/patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff
===================================================================
--- 
glibc-package/branches/glibc-2.22/debian/patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff
       2015-09-20 21:05:05 UTC (rev 6602)
+++ 
glibc-package/branches/glibc-2.22/debian/patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff
       2015-09-20 21:09:51 UTC (rev 6603)
@@ -4,18 +4,20 @@
 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
+Index: glibc-2.19/sysdeps/mach/hurd/recvmsg.c
+===================================================================
+--- glibc-2.19.orig/sysdeps/mach/hurd/recvmsg.c
++++ glibc-2.19/sysdeps/mach/hurd/recvmsg.c
 @@ -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 +25,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 +48,60 @@
  
    /* Find the total number of bytes to be read.  */
    amount = 0;
-@@ -135,6 +155,85 @@ __libc_recvmsg (int fd, struct msghdr *m
+@@ -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,61 +109,27 @@
 +      {
 +        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);
---- a/sysdeps/mach/hurd/sendmsg.c
-+++ b/sysdeps/mach/hurd/sendmsg.c
+ weak_alias (__libc_recvmsg, recvmsg)
+Index: glibc-2.19/sysdeps/mach/hurd/sendmsg.c
+===================================================================
+--- glibc-2.19.orig/sysdeps/mach/hurd/sendmsg.c
++++ glibc-2.19/sysdeps/mach/hurd/sendmsg.c
 @@ -32,6 +32,10 @@ ssize_t
  __libc_sendmsg (int fd, const struct msghdr *message, int flags)
  {
@@ -153,11 +149,11 @@
    int i;
  
    /* Find the total number of bytes to be written.  */
-@@ -101,6 +106,47 @@ __libc_sendmsg (int fd, const struct msg
+@@ -101,6 +106,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 +170,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 +198,7 @@
    if (addr)
      {
        if (addr->sun_family == AF_LOCAL)
-@@ -111,9 +157,8 @@ __libc_sendmsg (int fd, const struct msg
+@@ -111,9 +158,8 @@ __libc_sendmsg (int fd, const struct msg
          file_t file = __file_name_lookup (name, 0, 0);
          if (file == MACH_PORT_NULL)
            {
@@ -213,7 +210,7 @@
            }
          err = __ifsock_getsockaddr (file, &aport);
          __mach_port_deallocate (__mach_task_self (), file);
-@@ -121,11 +166,7 @@ __libc_sendmsg (int fd, const struct msg
+@@ -121,11 +167,7 @@ __libc_sendmsg (int fd, const struct msg
            /* The file did not grok the ifsock protocol.  */
            err = ENOTSOCK;
          if (err)
@@ -226,7 +223,7 @@
        }
        else
        err = EIEIO;
-@@ -144,8 +185,9 @@ __libc_sendmsg (int fd, const struct msg
+@@ -144,8 +186,9 @@ __libc_sendmsg (int fd, const struct msg
                              /* Send the data.  */
                              err = __socket_send (port, aport,
                                                   flags, data.ptr, len,
@@ -238,7 +235,7 @@
                                                   message->msg_control,
                                                   message->msg_controllen,
                                                   &amount);
-@@ -154,11 +196,19 @@ __libc_sendmsg (int fd, const struct msg
+@@ -154,11 +197,19 @@ __libc_sendmsg (int fd, const struct msg
                            }
                          err;
                        }));

Modified: glibc-package/branches/glibc-2.22/debian/patches/series
===================================================================
--- glibc-package/branches/glibc-2.22/debian/patches/series     2015-09-20 
21:05:05 UTC (rev 6602)
+++ glibc-package/branches/glibc-2.22/debian/patches/series     2015-09-20 
21:09:51 UTC (rev 6603)
@@ -76,6 +76,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 via email to