summaryrefslogtreecommitdiff
path: root/src/libsystemd
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2023-04-20 01:24:42 +0100
committerLuca Boccassi <bluca@debian.org>2023-04-25 00:54:07 +0100
commit7d9f6034a93c695c939bb6ae3a626727d5683523 (patch)
treedd98ab54802af849190567bfe991b9db58026162 /src/libsystemd
parent0593b34adcb79056767a5cfd70028a8222ee3cb7 (diff)
downloadsystemd-7d9f6034a93c695c939bb6ae3a626727d5683523.tar.gz
sd-bus: check for pid change before closing
If we try to close after a fork, the FDs will have been cloned too and we'll assert. This can happen for example in PAM modules. Avoid the macro and define ref/unref by hand to do the same check.
Diffstat (limited to 'src/libsystemd')
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 40dadf67a8..f4f2e350f3 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -1779,6 +1779,8 @@ _public_ void sd_bus_close(sd_bus *bus) {
_public_ sd_bus *sd_bus_close_unref(sd_bus *bus) {
if (!bus)
return NULL;
+ if (bus_pid_changed(bus))
+ return NULL;
sd_bus_close(bus);
@@ -1788,6 +1790,8 @@ _public_ sd_bus *sd_bus_close_unref(sd_bus *bus) {
_public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
if (!bus)
return NULL;
+ if (bus_pid_changed(bus))
+ return NULL;
/* Have to do this before flush() to prevent hang */
bus_kill_exec(bus);
@@ -1805,7 +1809,30 @@ void bus_enter_closing(sd_bus *bus) {
bus_set_state(bus, BUS_CLOSING);
}
-DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_bus, sd_bus, bus_free);
+/* Define manually so we can add the PID check */
+_public_ sd_bus *sd_bus_ref(sd_bus *bus) {
+ if (!bus)
+ return NULL;
+ if (bus_pid_changed(bus))
+ return NULL;
+
+ bus->n_ref++;
+
+ return bus;
+}
+
+_public_ sd_bus* sd_bus_unref(sd_bus *bus) {
+ if (!bus)
+ return NULL;
+ if (bus_pid_changed(bus))
+ return NULL;
+
+ assert(bus->n_ref > 0);
+ if (--bus->n_ref > 0)
+ return NULL;
+
+ return bus_free(bus);
+}
_public_ int sd_bus_is_open(sd_bus *bus) {
if (!bus)