]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: check for pid change before closing
authorLuca Boccassi <bluca@debian.org>
Thu, 20 Apr 2023 00:24:42 +0000 (01:24 +0100)
committerLuca Boccassi <bluca@debian.org>
Mon, 24 Apr 2023 23:54:07 +0000 (00:54 +0100)
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

index 40dadf67a88f26a770a13fb7e50797515b6c8c52..f4f2e350f3c1a352b4e254815047bd8cb4476cf3 100644 (file)
@@ -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)