X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-daemon%2Fsd-daemon.c;h=82ac72c72a0f8d48b583a1272722a237c296a6ae;hp=0842aba9cbfa4ebcfe62c75532743ccb75fefbbd;hb=64144440a5d2d94482f882b992fd2a4e0dca7a05;hpb=24bfda116ce2a627aebe3eba3ad71d34498f5545 diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index 0842aba9c..82ac72c72 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -350,12 +350,10 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char .msg_iovlen = 1, .msg_name = &sockaddr, }; - struct cmsghdr *control; _cleanup_close_ int fd = -1; struct cmsghdr *cmsg = NULL; const char *e; - size_t controllen_without_ucred = 0; - bool try_without_ucred = false; + bool have_pid; int r; if (!state) { @@ -394,42 +392,37 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char if (msghdr.msg_namelen > sizeof(struct sockaddr_un)) msghdr.msg_namelen = sizeof(struct sockaddr_un); - control = alloca(CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int) * n_fds)); + have_pid = pid != 0 && pid != getpid(); - if (n_fds > 0) { - msghdr.msg_control = control; - msghdr.msg_controllen = CMSG_LEN(sizeof(int) * n_fds); + if (n_fds > 0 || have_pid) { + msghdr.msg_controllen = CMSG_SPACE(sizeof(int) * n_fds) + + CMSG_SPACE(sizeof(struct ucred) * have_pid); + msghdr.msg_control = alloca(msghdr.msg_controllen); cmsg = CMSG_FIRSTHDR(&msghdr); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int) * n_fds); + if (n_fds > 0) { + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int) * n_fds); - memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * n_fds); - } - - if (pid != 0 && pid != getpid()) { - struct ucred *ucred; - - try_without_ucred = true; - controllen_without_ucred = msghdr.msg_controllen; + memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * n_fds); - msghdr.msg_control = control; - msghdr.msg_controllen += CMSG_LEN(sizeof(struct ucred)); + if (have_pid) + assert_se(cmsg = CMSG_NXTHDR(&msghdr, cmsg)); + } - if (cmsg) - cmsg = CMSG_NXTHDR(&msghdr, cmsg); - else - cmsg = CMSG_FIRSTHDR(&msghdr); + if (have_pid) { + struct ucred *ucred; - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_CREDENTIALS; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred)); - ucred = (struct ucred*) CMSG_DATA(cmsg); - ucred->pid = pid; - ucred->uid = getuid(); - ucred->gid = getgid(); + ucred = (struct ucred*) CMSG_DATA(cmsg); + ucred->pid = pid; + ucred->uid = getuid(); + ucred->gid = getgid(); + } } /* First try with fake ucred data, as requested */ @@ -439,10 +432,10 @@ _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 (try_without_ucred) { - if (controllen_without_ucred <= 0) + if (have_pid) { + msghdr.msg_controllen -= CMSG_SPACE(sizeof(struct ucred)); + if (msghdr.msg_controllen == 0) msghdr.msg_control = NULL; - msghdr.msg_controllen = controllen_without_ucred; if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0) { r = 1;