summaryrefslogtreecommitdiff
path: root/util/systemd.c
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2020-04-20 12:53:08 -0500
committerEric Blake <eblake@redhat.com>2020-05-04 14:54:35 -0500
commit474a6e64f2c3c17718b853b9d70e054ee8d26f37 (patch)
tree2cf2b2a0a8e525a7a82a7d2e8c329ef8f0c67672 /util/systemd.c
parent5375af3cd7b8adcc10c18d8083b7be63976c9645 (diff)
tools: Fix use of fcntl(F_SETFD) during socket activation
Blindly setting FD_CLOEXEC without a read-modify-write will inadvertently clear any other intentionally-set bits, such as a proposed new bit for designating a fd that must behave in 32-bit mode. However, we cannot use our wrapper qemu_set_cloexec(), because that wrapper intentionally abort()s on failure, whereas the probe here intentionally tolerates failure to deal with incorrect socket activation gracefully. Instead, fix the code to do the proper read-modify-write. Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <20200420175309.75894-3-eblake@redhat.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/systemd.c')
-rw-r--r--util/systemd.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/util/systemd.c b/util/systemd.c
index 1dd0367d9a..5bcac9b401 100644
--- a/util/systemd.c
+++ b/util/systemd.c
@@ -23,6 +23,7 @@ unsigned int check_socket_activation(void)
unsigned long nr_fds;
unsigned int i;
int fd;
+ int f;
int err;
s = getenv("LISTEN_PID");
@@ -54,7 +55,8 @@ unsigned int check_socket_activation(void)
/* So the file descriptors don't leak into child processes. */
for (i = 0; i < nr_fds; ++i) {
fd = FIRST_SOCKET_ACTIVATION_FD + i;
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
+ f = fcntl(fd, F_GETFD);
+ if (f == -1 || fcntl(fd, F_SETFD, f | FD_CLOEXEC) == -1) {
/* If we cannot set FD_CLOEXEC then it probably means the file
* descriptor is invalid, so socket activation has gone wrong
* and we should exit.