Pablo Greco 48fc63
From d06dfdde758e178d1ae20756890302a5c265ac08 Mon Sep 17 00:00:00 2001
Pablo Greco 48fc63
From: Lennart Poettering <lennart@poettering.net>
Pablo Greco 48fc63
Date: Fri, 5 Jan 2018 13:24:58 +0100
Pablo Greco 48fc63
Subject: [PATCH] sd-dameon: also sent ucred when our UID differs from EUID
Pablo Greco 48fc63
Pablo Greco 48fc63
Let's be explicit, and always send the messages from our UID and never
Pablo Greco 48fc63
our EUID. Previously this behaviour was conditionalized only on whether
Pablo Greco 48fc63
the PID was specified, which made this non-obvious.
Pablo Greco 48fc63
Pablo Greco 48fc63
(cherry picked from commit 9e1d021ee3f147486c5cfac69b3cbf6f4b36eb79)
Pablo Greco 48fc63
Pablo Greco 48fc63
Related: #1663143
Pablo Greco 48fc63
---
Pablo Greco 48fc63
 src/libsystemd/sd-daemon/sd-daemon.c | 39 +++++++++++++++++++---------
Pablo Greco 48fc63
 1 file changed, 27 insertions(+), 12 deletions(-)
Pablo Greco 48fc63
Pablo Greco 48fc63
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
Pablo Greco 48fc63
index 2c4dd9d225..82483a38e6 100644
Pablo Greco 48fc63
--- a/src/libsystemd/sd-daemon/sd-daemon.c
Pablo Greco 48fc63
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
Pablo Greco 48fc63
@@ -40,6 +40,8 @@
Pablo Greco 48fc63
 #include "socket-util.h"
Pablo Greco 48fc63
 #include "sd-daemon.h"
Pablo Greco 48fc63
 
Pablo Greco 48fc63
+#define SNDBUF_SIZE (8*1024*1024)
Pablo Greco 48fc63
+
Pablo Greco 48fc63
 _public_ int sd_listen_fds(int unset_environment) {
Pablo Greco 48fc63
         const char *e;
Pablo Greco 48fc63
         unsigned n;
Pablo Greco 48fc63
@@ -340,7 +342,13 @@ _public_ int sd_is_mq(int fd, const char *path) {
Pablo Greco 48fc63
         return 1;
Pablo Greco 48fc63
 }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-_public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char *state, const int *fds, unsigned n_fds) {
Pablo Greco 48fc63
+_public_ int sd_pid_notify_with_fds(
Pablo Greco 48fc63
+                pid_t pid,
Pablo Greco 48fc63
+                int unset_environment,
Pablo Greco 48fc63
+                const char *state,
Pablo Greco 48fc63
+                const int *fds,
Pablo Greco 48fc63
+                unsigned n_fds) {
Pablo Greco 48fc63
+
Pablo Greco 48fc63
         union sockaddr_union sockaddr = {
Pablo Greco 48fc63
                 .sa.sa_family = AF_UNIX,
Pablo Greco 48fc63
         };
Pablo Greco 48fc63
@@ -355,7 +363,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
Pablo Greco 48fc63
         _cleanup_close_ int fd = -1;
Pablo Greco 48fc63
         struct cmsghdr *cmsg = NULL;
Pablo Greco 48fc63
         const char *e;
Pablo Greco 48fc63
-        bool have_pid;
Pablo Greco 48fc63
+        bool send_ucred;
Pablo Greco 48fc63
         int r;
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         if (!state) {
Pablo Greco 48fc63
@@ -384,6 +392,8 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
Pablo Greco 48fc63
                 goto finish;
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
+        (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
Pablo Greco 48fc63
+
Pablo Greco 48fc63
         iovec.iov_len = strlen(state);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path));
Pablo Greco 48fc63
@@ -394,13 +404,18 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
Pablo Greco 48fc63
         if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
Pablo Greco 48fc63
                 msghdr.msg_namelen = sizeof(struct sockaddr_un);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        have_pid = pid != 0 && pid != getpid();
Pablo Greco 48fc63
+        send_ucred =
Pablo Greco 48fc63
+                (pid != 0 && pid != getpid()) ||
Pablo Greco 48fc63
+                getuid() != geteuid() ||
Pablo Greco 48fc63
+                getgid() != getegid();
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+        if (n_fds > 0 || send_ucred) {
Pablo Greco 48fc63
+                /* CMSG_SPACE(0) may return value different than zero, which results in miscalculated controllen. */
Pablo Greco 48fc63
+                msghdr.msg_controllen =
Pablo Greco 48fc63
+                        (n_fds > 0 ? CMSG_SPACE(sizeof(int) * n_fds) : 0) +
Pablo Greco 48fc63
+                        (send_ucred ? CMSG_SPACE(sizeof(struct ucred)) : 0);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        if (n_fds > 0 || have_pid) {
Pablo Greco 48fc63
-                /* CMSG_SPACE(0) may return value different then zero, which results in miscalculated controllen. */
Pablo Greco 48fc63
-                msghdr.msg_controllen = (n_fds ? CMSG_SPACE(sizeof(int) * n_fds) : 0) +
Pablo Greco 48fc63
-                                        CMSG_SPACE(sizeof(struct ucred)) * have_pid;
Pablo Greco 48fc63
-                msghdr.msg_control = alloca(msghdr.msg_controllen);
Pablo Greco 48fc63
+                msghdr.msg_control = alloca0(msghdr.msg_controllen);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                 cmsg = CMSG_FIRSTHDR(&msghdr);
Pablo Greco 48fc63
                 if (n_fds > 0) {
Pablo Greco 48fc63
@@ -410,11 +425,11 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                         memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * n_fds);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-                        if (have_pid)
Pablo Greco 48fc63
+                        if (send_ucred)
Pablo Greco 48fc63
                                 assert_se(cmsg = CMSG_NXTHDR(&msghdr, cmsg));
Pablo Greco 48fc63
                 }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-                if (have_pid) {
Pablo Greco 48fc63
+                if (send_ucred) {
Pablo Greco 48fc63
                         struct ucred *ucred;
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                         cmsg->cmsg_level = SOL_SOCKET;
Pablo Greco 48fc63
@@ -422,7 +437,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
Pablo Greco 48fc63
                         cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                         ucred = (struct ucred*) CMSG_DATA(cmsg);
Pablo Greco 48fc63
-                        ucred->pid = pid;
Pablo Greco 48fc63
+                        ucred->pid = pid != 0 ? pid : getpid();
Pablo Greco 48fc63
                         ucred->uid = getuid();
Pablo Greco 48fc63
                         ucred->gid = getgid();
Pablo Greco 48fc63
                 }
Pablo Greco 48fc63
@@ -435,7 +450,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         /* If that failed, try with our own ucred instead */
Pablo Greco 48fc63
-        if (have_pid) {
Pablo Greco 48fc63
+        if (send_ucred) {
Pablo Greco 48fc63
                 msghdr.msg_controllen -= CMSG_SPACE(sizeof(struct ucred));
Pablo Greco 48fc63
                 if (msghdr.msg_controllen == 0)
Pablo Greco 48fc63
                         msghdr.msg_control = NULL;