_dbus_server_new_for_socket: Iterate over arrays as intended
authorSimon McVittie <smcv@collabora.com>
Mon, 27 Nov 2017 16:23:16 +0000 (16:23 +0000)
committerSimon McVittie <smcv@collabora.com>
Mon, 27 Nov 2017 19:48:36 +0000 (19:48 +0000)
Commit 0c03b505 was meant to clear all the fds indexed by j in
[0, n_fds), which socket_disconnect() can't be allowed to close
(because on failure the caller remains responsible for closing them);
but instead it closed the one we failed to add to the main loop
(fd i), repeatedly.

Similarly, it was meant to invalidate all the watches indexed by j
in [i, n_fds) (the one we failed to add to the main loop and the ones
we didn't try to add to the main loop yet), which socket_disconnect()
can't be allowed to see (because it would fail to remove them from
the main loop and hit an assertion failure); but instead it invalidated
fd i, repeatedly.

These happen to be the same thing if you only have one fd, resulting
in the test-case passing on an IPv4-only system, but failing on a
system with both IPv4 and IPv6.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=89104
Signed-off-by: Simon McVittie <smcv@collabora.com>
Reviewed-by: Philip Withnall <withnall@endlessm.com>
(cherry picked from commit c9aa00ce730f9741ab39ff704e46ec33dd4a11ea)

dbus/dbus-server-socket.c

index 42d7145..6a93091 100644 (file)
@@ -346,16 +346,16 @@ _dbus_server_new_for_socket (DBusSocket       *fds,
            * we return successfully, so don't let socket_disconnect()
            * close them */
           for (j = 0; j < n_fds; j++)
-            _dbus_socket_invalidate (&socket_server->fds[i]);
+            _dbus_socket_invalidate (&socket_server->fds[j]);
 
           /* socket_disconnect() will try to remove all the watches;
            * make sure it doesn't see the ones that weren't even added
            * yet */
           for (j = i; j < n_fds; j++)
             {
-              _dbus_watch_invalidate (socket_server->watch[i]);
-              _dbus_watch_unref (socket_server->watch[i]);
-              socket_server->watch[i] = NULL;
+              _dbus_watch_invalidate (socket_server->watch[j]);
+              _dbus_watch_unref (socket_server->watch[j]);
+              socket_server->watch[j] = NULL;
             }
 
           _dbus_server_disconnect_unlocked (server);