diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index ba383e0b3b..83ff7d4277 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -455,7 +455,13 @@ _public_ int sd_is_mq(int fd, const char *path) { return 1; } -_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, }; @@ -470,7 +476,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) { @@ -504,7 +510,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); @@ -514,13 +520,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); @@ -532,11 +541,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; @@ -544,7 +553,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(); } @@ -557,7 +566,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;