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.
120 lines
4.8 KiB
120 lines
4.8 KiB
5 years ago
|
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;
|