forked from qemu/qemu
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
qemu-ga: obey LISTEN_PID when using systemd socket activation
qemu-ga's socket activation support was not obeying the LISTEN_PID environment variable, which avoids that a process uses a socket-activation file descriptor meant for its parent. Mess can for example ensue if a process forks a children before consuming the socket-activation file descriptor and therefore setting O_CLOEXEC on it. Luckily, qemu-nbd also got socket activation code, and its copy does support LISTEN_PID. Some extra fixups are needed to ensure that the code can be used for both, but that's what this patch does. The main change is to replace get_listen_fds's "consume" argument with the FIRST_SOCKET_ACTIVATION_FD macro from the qemu-nbd code. Cc: "Richard W.M. Jones" <[email protected]> Cc: Stefan Hajnoczi <[email protected]> Reviewed-by: Daniel P. Berrange <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
- Loading branch information
Showing
5 changed files
with
125 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* systemd socket activation support | ||
* | ||
* Copyright 2017 Red Hat, Inc. and/or its affiliates | ||
* | ||
* Authors: | ||
* Richard W.M. Jones <[email protected]> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2 or later. | ||
* See the COPYING file in the top-level directory. | ||
*/ | ||
|
||
#ifndef QEMU_SYSTEMD_H | ||
#define QEMU_SYSTEMD_H 1 | ||
|
||
#define FIRST_SOCKET_ACTIVATION_FD 3 /* defined by systemd ABI */ | ||
|
||
/* | ||
* Check if socket activation was requested via use of the | ||
* LISTEN_FDS and LISTEN_PID environment variables. | ||
* | ||
* Returns 0 if no socket activation, or the number of FDs. | ||
*/ | ||
unsigned int check_socket_activation(void); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,3 +42,4 @@ util-obj-y += log.o | |
util-obj-y += qdist.o | ||
util-obj-y += qht.o | ||
util-obj-y += range.o | ||
util-obj-y += systemd.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* systemd socket activation support | ||
* | ||
* Copyright 2017 Red Hat, Inc. and/or its affiliates | ||
* | ||
* Authors: | ||
* Richard W.M. Jones <[email protected]> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2 or later. | ||
* See the COPYING file in the top-level directory. | ||
*/ | ||
|
||
#include "qemu/osdep.h" | ||
#include "qemu/systemd.h" | ||
#include "qemu/cutils.h" | ||
#include "qemu/error-report.h" | ||
|
||
#ifndef _WIN32 | ||
unsigned int check_socket_activation(void) | ||
{ | ||
const char *s; | ||
unsigned long pid; | ||
unsigned long nr_fds; | ||
unsigned int i; | ||
int fd; | ||
int err; | ||
|
||
s = getenv("LISTEN_PID"); | ||
if (s == NULL) { | ||
return 0; | ||
} | ||
err = qemu_strtoul(s, NULL, 10, &pid); | ||
if (err) { | ||
return 0; | ||
} | ||
if (pid != getpid()) { | ||
return 0; | ||
} | ||
|
||
s = getenv("LISTEN_FDS"); | ||
if (s == NULL) { | ||
return 0; | ||
} | ||
err = qemu_strtoul(s, NULL, 10, &nr_fds); | ||
if (err) { | ||
return 0; | ||
} | ||
assert(nr_fds <= UINT_MAX); | ||
|
||
/* So these are not passed to any child processes we might start. */ | ||
unsetenv("LISTEN_FDS"); | ||
unsetenv("LISTEN_PID"); | ||
|
||
/* 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) { | ||
/* 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. | ||
*/ | ||
error_report("Socket activation failed: " | ||
"invalid file descriptor fd = %d: %m", | ||
fd); | ||
exit(EXIT_FAILURE); | ||
} | ||
} | ||
|
||
return (unsigned int) nr_fds; | ||
} | ||
|
||
#else /* !_WIN32 */ | ||
unsigned int check_socket_activation(void) | ||
{ | ||
return 0; | ||
} | ||
#endif |