chiark / gitweb /
bus: fix use-after-free in slot-release
authorDavid Herrmann <dh.herrmann@gmail.com>
Thu, 28 Aug 2014 10:42:03 +0000 (12:42 +0200)
committerDavid Herrmann <dh.herrmann@gmail.com>
Thu, 28 Aug 2014 10:45:51 +0000 (12:45 +0200)
We must not access slot->floating after we possible dropped the last
reference to it. Fix all callback-invocations to first check
slot->floating and possible disconnect the slot, then release the last
reference.

src/libsystemd/sd-bus/sd-bus.c

index a204d675901c2633c1a1f5c1c65f79a92b2d0ad0..8caa404227c2c9e4bfa3bb56d4dc460b850e99a1 100644 (file)
@@ -2107,7 +2107,7 @@ static int process_timeout(sd_bus *bus) {
         r = c->callback(bus, m, slot->userdata, &error_buffer);
         bus->current_userdata = NULL;
         bus->current_handler = NULL;
-        bus->current_slot = sd_bus_slot_unref(slot);
+        bus->current_slot = NULL;
         bus->current_message = NULL;
 
         if (slot->floating) {
@@ -2115,6 +2115,8 @@ static int process_timeout(sd_bus *bus) {
                 sd_bus_slot_unref(slot);
         }
 
+        sd_bus_slot_unref(slot);
+
         return bus_maybe_reply_error(m, r, &error_buffer);
 }
 
@@ -2203,13 +2205,15 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) {
         r = c->callback(bus, m, slot->userdata, &error_buffer);
         bus->current_userdata = NULL;
         bus->current_handler = NULL;
-        bus->current_slot = sd_bus_slot_unref(slot);
+        bus->current_slot = NULL;
 
         if (slot->floating) {
                 bus_slot_disconnect(slot);
                 sd_bus_slot_unref(slot);
         }
 
+        sd_bus_slot_unref(slot);
+
         return bus_maybe_reply_error(m, r, &error_buffer);
 }
 
@@ -2529,7 +2533,7 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
                 r = c->callback(bus, m, slot->userdata, &error_buffer);
                 bus->current_userdata = NULL;
                 bus->current_handler = NULL;
-                bus->current_slot = sd_bus_slot_unref(slot);
+                bus->current_slot = NULL;
                 bus->current_message = NULL;
 
                 if (slot->floating) {
@@ -2537,6 +2541,8 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
                         sd_bus_slot_unref(slot);
                 }
 
+                sd_bus_slot_unref(slot);
+
                 return bus_maybe_reply_error(m, r, &error_buffer);
         }