From 7d9f6034a93c695c939bb6ae3a626727d5683523 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Thu, 20 Apr 2023 01:24:42 +0100 Subject: 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. --- src/libsystemd/sd-bus/sd-bus.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'src/libsystemd') 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) -- cgit v1.2.1