richardphibel / rpms / systemd

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