You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
4.8 KiB
119 lines
4.8 KiB
From d06dfdde758e178d1ae20756890302a5c265ac08 Mon Sep 17 00:00:00 2001 |
|
From: Lennart Poettering <lennart@poettering.net> |
|
Date: Fri, 5 Jan 2018 13:24:58 +0100 |
|
Subject: [PATCH] sd-dameon: also sent ucred when our UID differs from EUID |
|
|
|
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. |
|
|
|
(cherry picked from commit 9e1d021ee3f147486c5cfac69b3cbf6f4b36eb79) |
|
|
|
Related: #1663143 |
|
--- |
|
src/libsystemd/sd-daemon/sd-daemon.c | 39 +++++++++++++++++++--------- |
|
1 file changed, 27 insertions(+), 12 deletions(-) |
|
|
|
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c |
|
index 2c4dd9d225..82483a38e6 100644 |
|
--- a/src/libsystemd/sd-daemon/sd-daemon.c |
|
+++ b/src/libsystemd/sd-daemon/sd-daemon.c |
|
@@ -40,6 +40,8 @@ |
|
#include "socket-util.h" |
|
#include "sd-daemon.h" |
|
|
|
+#define SNDBUF_SIZE (8*1024*1024) |
|
+ |
|
_public_ int sd_listen_fds(int unset_environment) { |
|
const char *e; |
|
unsigned n; |
|
@@ -340,7 +342,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, |
|
}; |
|
@@ -355,7 +363,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) { |
|
@@ -384,6 +392,8 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char |
|
goto finish; |
|
} |
|
|
|
+ (void) fd_inc_sndbuf(fd, SNDBUF_SIZE); |
|
+ |
|
iovec.iov_len = strlen(state); |
|
|
|
strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path)); |
|
@@ -394,13 +404,18 @@ _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); |
|
|
|
- have_pid = pid != 0 && pid != getpid(); |
|
+ send_ucred = |
|
+ (pid != 0 && pid != getpid()) || |
|
+ getuid() != geteuid() || |
|
+ getgid() != getegid(); |
|
+ |
|
+ 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) + |
|
+ (send_ucred ? CMSG_SPACE(sizeof(struct ucred)) : 0); |
|
|
|
- if (n_fds > 0 || have_pid) { |
|
- /* CMSG_SPACE(0) may return value different then zero, which results in miscalculated controllen. */ |
|
- msghdr.msg_controllen = (n_fds ? CMSG_SPACE(sizeof(int) * n_fds) : 0) + |
|
- CMSG_SPACE(sizeof(struct ucred)) * have_pid; |
|
- msghdr.msg_control = alloca(msghdr.msg_controllen); |
|
+ msghdr.msg_control = alloca0(msghdr.msg_controllen); |
|
|
|
cmsg = CMSG_FIRSTHDR(&msghdr); |
|
if (n_fds > 0) { |
|
@@ -410,11 +425,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; |
|
@@ -422,7 +437,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(); |
|
ucred->uid = getuid(); |
|
ucred->gid = getgid(); |
|
} |
|
@@ -435,7 +450,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;
|
|
|