chiark / gitweb /
sd-dameon: also sent ucred when our UID differs from EUID
authorLennart Poettering <lennart@poettering.net>
Fri, 5 Jan 2018 12:24:58 +0000 (13:24 +0100)
committerSven Eden <yamakuzure@gmx.net>
Wed, 30 May 2018 05:50:08 +0000 (07:50 +0200)
Let's be explicit, and always send the messages from our UID and never
our EUID. Previously this behaviour was conditionalized only on whether
the PID was specified, which made this non-obvious.

src/libelogind/sd-daemon/sd-daemon.c

index 147042c9aec829d94304dde7b62b98d122810cfa..b7ae99a4db149a39878c577db7a4be7b6f298664 100644 (file)
@@ -39,7 +39,6 @@
 #include "fs-util.h"
 #include "parse-util.h"
 #include "path-util.h"
-//#include "process-util.h"
 #include "socket-util.h"
 #include "strv.h"
 #include "util.h"
@@ -461,7 +460,13 @@ _public_ int sd_is_mq(int fd, const char *path) {
 }
 #endif // 0
 
-_public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char *state, const int *fds, unsigned n_fds) {
+_public_ int sd_pid_notify_with_fds(
+                pid_t pid,
+                int unset_environment,
+                const char *state,
+                const int *fds,
+                unsigned n_fds) {
+
         union sockaddr_union sockaddr = {
                 .sa.sa_family = AF_UNIX,
         };
@@ -476,7 +481,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
         _cleanup_close_ int fd = -1;
         struct cmsghdr *cmsg = NULL;
         const char *e;
-        bool have_pid;
+        bool send_ucred;
         int r;
 
         if (!state) {
@@ -510,7 +515,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
                 goto finish;
         }
 
-        fd_inc_sndbuf(fd, SNDBUF_SIZE);
+        (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
 
         iovec.iov_len = strlen(state);
 
@@ -520,13 +525,16 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
 
         msghdr.msg_namelen = SOCKADDR_UN_LEN(sockaddr.un);
 
-        have_pid = pid != 0 && pid != getpid_cached();
+        send_ucred =
+                (pid != 0 && pid != getpid_cached()) ||
+                getuid() != geteuid() ||
+                getgid() != getegid();
 
-        if (n_fds > 0 || have_pid) {
+        if (n_fds > 0 || send_ucred) {
                 /* CMSG_SPACE(0) may return value different than zero, which results in miscalculated controllen. */
                 msghdr.msg_controllen =
                         (n_fds > 0 ? CMSG_SPACE(sizeof(int) * n_fds) : 0) +
-                        (have_pid ? CMSG_SPACE(sizeof(struct ucred)) : 0);
+                        (send_ucred ? CMSG_SPACE(sizeof(struct ucred)) : 0);
 
                 msghdr.msg_control = alloca0(msghdr.msg_controllen);
 
@@ -538,11 +546,11 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
 
                         memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * n_fds);
 
-                        if (have_pid)
+                        if (send_ucred)
                                 assert_se(cmsg = CMSG_NXTHDR(&msghdr, cmsg));
                 }
 
-                if (have_pid) {
+                if (send_ucred) {
                         struct ucred *ucred;
 
                         cmsg->cmsg_level = SOL_SOCKET;
@@ -550,7 +558,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
                         cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
 
                         ucred = (struct ucred*) CMSG_DATA(cmsg);
-                        ucred->pid = pid;
+                        ucred->pid = pid != 0 ? pid : getpid_cached();
                         ucred->uid = getuid();
                         ucred->gid = getgid();
                 }
@@ -563,7 +571,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
         }
 
         /* If that failed, try with our own ucred instead */
-        if (have_pid) {
+        if (send_ucred) {
                 msghdr.msg_controllen -= CMSG_SPACE(sizeof(struct ucred));
                 if (msghdr.msg_controllen == 0)
                         msghdr.msg_control = NULL;