dbus-spawn: don't leave bad file descriptors being watched
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Tue, 11 Jan 2011 19:57:31 +0000 (19:57 +0000)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Fri, 21 Jan 2011 15:00:25 +0000 (15:00 +0000)
The code called from handle_watch() might close either or both of the
sockets we're watching, without cleaning up the DBusWatch. This results
in invalid file descriptors being passed to _dbus_poll(), which could
end up busy-looping on a POLLNVAL condition until the babysitter loses
its last ref (which automatically clears up both watches).

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=32992
Bug-NB: NB#200248
Reviewed-by: Colin Walters <walters@verbum.org>
dbus/dbus-spawn.c

index dcd111d..a1bab3d 100644 (file)
@@ -774,7 +774,32 @@ handle_watch (DBusWatch       *watch,
   while (LIVE_CHILDREN (sitter) &&
          babysitter_iteration (sitter, FALSE))
     ;
-  
+
+  /* Those might have closed the sockets we're watching. Before returning
+   * to the main loop, we must sort that out. */
+
+  if (sitter->error_watch != NULL && sitter->error_pipe_from_child == -1)
+    {
+      _dbus_watch_invalidate (sitter->error_watch);
+
+      if (sitter->watches != NULL)
+        _dbus_watch_list_remove_watch (sitter->watches,  sitter->error_watch);
+
+      _dbus_watch_unref (sitter->error_watch);
+      sitter->error_watch = NULL;
+    }
+
+  if (sitter->sitter_watch != NULL && sitter->socket_to_babysitter == -1)
+    {
+      _dbus_watch_invalidate (sitter->sitter_watch);
+
+      if (sitter->watches != NULL)
+        _dbus_watch_list_remove_watch (sitter->watches,  sitter->sitter_watch);
+
+      _dbus_watch_unref (sitter->sitter_watch);
+      sitter->sitter_watch = NULL;
+    }
+
   return TRUE;
 }