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=028c2a7a5b4cceb881207ee23fa2bff511196933;hb=64144440a5d2d94482f882b992fd2a4e0dca7a05;hpb=a354329f724d6ce913d2ccffb2be8f3327a67faa
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index 028c2a7a5..82ac72c72 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -19,11 +19,9 @@
along with systemd; If not, see .
***/
-#include
#include
#include
#include
-#include
#include
#include
#include
@@ -352,16 +350,10 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
.msg_iovlen = 1,
.msg_name = &sockaddr,
};
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
- CMSG_SPACE(sizeof(int) * n_fds)];
- } 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) {
@@ -400,40 +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);
- if (n_fds > 0) {
- msghdr.msg_control = &control;
- msghdr.msg_controllen = CMSG_LEN(sizeof(int) * n_fds);
+ have_pid = pid != 0 && pid != getpid();
- cmsg = CMSG_FIRSTHDR(&msghdr);
- 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 (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);
- if (pid != 0 && pid != getpid()) {
- struct ucred *ucred;
+ cmsg = CMSG_FIRSTHDR(&msghdr);
+ if (n_fds > 0) {
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int) * n_fds);
- 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 */
@@ -443,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;