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