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