diff options
author | Luca Boccassi <bluca@debian.org> | 2023-04-20 01:24:42 +0100 |
---|---|---|
committer | Luca Boccassi <bluca@debian.org> | 2023-04-25 00:54:07 +0100 |
commit | 7d9f6034a93c695c939bb6ae3a626727d5683523 (patch) | |
tree | dd98ab54802af849190567bfe991b9db58026162 /src/libsystemd | |
parent | 0593b34adcb79056767a5cfd70028a8222ee3cb7 (diff) | |
download | systemd-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.c | 29 |
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) |