Signed-off-by: Clemens Gruber <clemens.gru...@pqgruber.com> --- ...r_new_for_socket-Invalidate-watches-durin.patch | 28 +++++ ...r_new_for_socket-Properly-disconnect-duri.patch | 124 +++++++++++++++++++++ ...n_tcp_socket-Don-t-rely-on-dbus_realloc-s.patch | 37 ++++++ ...r_new_for_socket-Iterate-over-arrays-as-i.patch | 54 +++++++++ patches/dbus-1.12.2/series | 7 ++ 5 files changed, 250 insertions(+) create mode 100644 patches/dbus-1.12.2/0001-_dbus_server_new_for_socket-Invalidate-watches-durin.patch create mode 100644 patches/dbus-1.12.2/0002-_dbus_server_new_for_socket-Properly-disconnect-duri.patch create mode 100644 patches/dbus-1.12.2/0003-_dbus_listen_tcp_socket-Don-t-rely-on-dbus_realloc-s.patch create mode 100644 patches/dbus-1.12.2/0004-_dbus_server_new_for_socket-Iterate-over-arrays-as-i.patch create mode 100644 patches/dbus-1.12.2/series
diff --git a/patches/dbus-1.12.2/0001-_dbus_server_new_for_socket-Invalidate-watches-durin.patch b/patches/dbus-1.12.2/0001-_dbus_server_new_for_socket-Invalidate-watches-durin.patch new file mode 100644 index 000000000..0a024be7f --- /dev/null +++ b/patches/dbus-1.12.2/0001-_dbus_server_new_for_socket-Invalidate-watches-durin.patch @@ -0,0 +1,28 @@ +From: Simon McVittie <s...@collabora.com> +Date: Tue, 21 Nov 2017 14:36:02 +0000 +Subject: [PATCH] _dbus_server_new_for_socket: Invalidate watches during error + unwinding + +We assert that every watch is invalidated before it is freed, but +in some OOM code paths this didn't happen. + +Signed-off-by: Simon McVittie <s...@collabora.com> +Reviewed-by: Philip Withnall <withn...@endlessm.com> +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=89104 +(cherry picked from commit 1ce34beef85a7a0b3c25890837e3a72f8bdac1f0) +--- + dbus/dbus-server-socket.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dbus/dbus-server-socket.c b/dbus/dbus-server-socket.c +index d716f500234d..61e143ba9e43 100644 +--- a/dbus/dbus-server-socket.c ++++ b/dbus/dbus-server-socket.c +@@ -358,6 +358,7 @@ _dbus_server_new_for_socket (DBusSocket *fds, + { + if (socket_server->watch[i] != NULL) + { ++ _dbus_watch_invalidate (socket_server->watch[i]); + _dbus_watch_unref (socket_server->watch[i]); + socket_server->watch[i] = NULL; + } diff --git a/patches/dbus-1.12.2/0002-_dbus_server_new_for_socket-Properly-disconnect-duri.patch b/patches/dbus-1.12.2/0002-_dbus_server_new_for_socket-Properly-disconnect-duri.patch new file mode 100644 index 000000000..e01e12786 --- /dev/null +++ b/patches/dbus-1.12.2/0002-_dbus_server_new_for_socket-Properly-disconnect-duri.patch @@ -0,0 +1,124 @@ +From: Simon McVittie <s...@collabora.com> +Date: Tue, 21 Nov 2017 14:38:13 +0000 +Subject: [PATCH] _dbus_server_new_for_socket: Properly disconnect during error + unwinding + +_dbus_server_finalize_base() asserts that the socket has been +disconnected, but in some OOM code paths we would call it without +officially disconnecting. Do so. + +This means we need to be a bit more careful about what is +socket_disconnect()'s responsibility to clean up, what is +_dbus_server_new_for_socket()'s responsibility, and what is the caller's +responsibility. + +Signed-off-by: Simon McVittie <s...@collabora.com> +Reviewed-by: Philip Withnall <withn...@endlessm.com> +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=89104 +(cherry picked from commit 0c03b505a9718c6d497caffb7d6083371679a852) +--- + dbus/dbus-server-protected.h | 1 + + dbus/dbus-server-socket.c | 27 ++++++++++++++++++++++----- + dbus/dbus-server.c | 24 +++++++++++++++--------- + 3 files changed, 38 insertions(+), 14 deletions(-) + +diff --git a/dbus/dbus-server-protected.h b/dbus/dbus-server-protected.h +index f613bf34e0d8..5664b2b4e150 100644 +--- a/dbus/dbus-server-protected.h ++++ b/dbus/dbus-server-protected.h +@@ -96,6 +96,7 @@ dbus_bool_t _dbus_server_init_base (DBusServer *server, + const DBusString *address, + DBusError *error); + void _dbus_server_finalize_base (DBusServer *server); ++void _dbus_server_disconnect_unlocked (DBusServer *server); + dbus_bool_t _dbus_server_add_watch (DBusServer *server, + DBusWatch *watch); + void _dbus_server_remove_watch (DBusServer *server, +diff --git a/dbus/dbus-server-socket.c b/dbus/dbus-server-socket.c +index 61e143ba9e43..42d71450b051 100644 +--- a/dbus/dbus-server-socket.c ++++ b/dbus/dbus-server-socket.c +@@ -243,8 +243,11 @@ socket_disconnect (DBusServer *server) + socket_server->watch[i] = NULL; + } + +- _dbus_close_socket (socket_server->fds[i], NULL); +- _dbus_socket_invalidate (&socket_server->fds[i]); ++ if (_dbus_socket_is_valid (socket_server->fds[i])) ++ { ++ _dbus_close_socket (socket_server->fds[i], NULL); ++ _dbus_socket_invalidate (&socket_server->fds[i]); ++ } + } + + if (socket_server->socket_name != NULL) +@@ -338,10 +341,24 @@ _dbus_server_new_for_socket (DBusSocket *fds, + socket_server->watch[i])) + { + int j; +- for (j = 0 ; j < i ; j++) +- _dbus_server_remove_watch (server, +- socket_server->watch[j]); + ++ /* The caller is still responsible for closing the fds until ++ * 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]); ++ ++ /* 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_server_disconnect_unlocked (server); + SERVER_UNLOCK (server); + _dbus_server_finalize_base (&socket_server->base); + goto failed_2; +diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c +index ea9aff2dbe45..d91df8325cd7 100644 +--- a/dbus/dbus-server.c ++++ b/dbus/dbus-server.c +@@ -764,6 +764,20 @@ dbus_server_unref (DBusServer *server) + } + } + ++void ++_dbus_server_disconnect_unlocked (DBusServer *server) ++{ ++ _dbus_assert (server->vtable->disconnect != NULL); ++ ++ if (!server->disconnected) ++ { ++ /* this has to be first so recursive calls to disconnect don't happen */ ++ server->disconnected = TRUE; ++ ++ (* server->vtable->disconnect) (server); ++ } ++} ++ + /** + * Releases the server's address and stops listening for + * new clients. If called more than once, only the first +@@ -780,15 +794,7 @@ dbus_server_disconnect (DBusServer *server) + dbus_server_ref (server); + SERVER_LOCK (server); + +- _dbus_assert (server->vtable->disconnect != NULL); +- +- if (!server->disconnected) +- { +- /* this has to be first so recursive calls to disconnect don't happen */ +- server->disconnected = TRUE; +- +- (* server->vtable->disconnect) (server); +- } ++ _dbus_server_disconnect_unlocked (server); + + SERVER_UNLOCK (server); + dbus_server_unref (server); diff --git a/patches/dbus-1.12.2/0003-_dbus_listen_tcp_socket-Don-t-rely-on-dbus_realloc-s.patch b/patches/dbus-1.12.2/0003-_dbus_listen_tcp_socket-Don-t-rely-on-dbus_realloc-s.patch new file mode 100644 index 000000000..d3c637d56 --- /dev/null +++ b/patches/dbus-1.12.2/0003-_dbus_listen_tcp_socket-Don-t-rely-on-dbus_realloc-s.patch @@ -0,0 +1,37 @@ +From: Simon McVittie <s...@collabora.com> +Date: Tue, 21 Nov 2017 14:43:01 +0000 +Subject: [PATCH] _dbus_listen_tcp_socket: Don't rely on dbus_realloc setting + errno + +dbus_realloc() doesn't guarantee to set errno (if it did, the +only reasonable thing it could set it to would be ENOMEM). In +particular, faking OOM conditions doesn't set it. This can cause an +assertion failure when OOM tests assert that the only error that can +validly occur is DBUS_ERROR_NO_MEMORY. + +Signed-off-by: Simon McVittie <s...@collabora.com> +Reviewed-by: Philip Withnall <withn...@endlessm.com> +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=89104 +(cherry picked from commit 9ded6907e66b89c3c74620a4485e8f752f092a60) +--- + dbus/dbus-sysdeps-unix.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c +index bebf2073b680..b0ba89919dab 100644 +--- a/dbus/dbus-sysdeps-unix.c ++++ b/dbus/dbus-sysdeps-unix.c +@@ -1576,11 +1576,9 @@ _dbus_listen_tcp_socket (const char *host, + newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1)); + if (!newlisten_fd) + { +- saved_errno = errno; + _dbus_close (fd, NULL); +- dbus_set_error (error, _dbus_error_from_errno (saved_errno), +- "Failed to allocate file handle array: %s", +- _dbus_strerror (saved_errno)); ++ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, ++ "Failed to allocate file handle array"); + goto failed; + } + listen_fd = newlisten_fd; diff --git a/patches/dbus-1.12.2/0004-_dbus_server_new_for_socket-Iterate-over-arrays-as-i.patch b/patches/dbus-1.12.2/0004-_dbus_server_new_for_socket-Iterate-over-arrays-as-i.patch new file mode 100644 index 000000000..eb0270aa0 --- /dev/null +++ b/patches/dbus-1.12.2/0004-_dbus_server_new_for_socket-Iterate-over-arrays-as-i.patch @@ -0,0 +1,54 @@ +From: Simon McVittie <s...@collabora.com> +Date: Mon, 27 Nov 2017 16:23:16 +0000 +Subject: [PATCH] _dbus_server_new_for_socket: Iterate over arrays as intended + +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 <s...@collabora.com> +Reviewed-by: Philip Withnall <withn...@endlessm.com> +(cherry picked from commit c9aa00ce730f9741ab39ff704e46ec33dd4a11ea) +--- + dbus/dbus-server-socket.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/dbus/dbus-server-socket.c b/dbus/dbus-server-socket.c +index 42d71450b051..6a93091a2291 100644 +--- a/dbus/dbus-server-socket.c ++++ b/dbus/dbus-server-socket.c +@@ -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); diff --git a/patches/dbus-1.12.2/series b/patches/dbus-1.12.2/series new file mode 100644 index 000000000..ddb681448 --- /dev/null +++ b/patches/dbus-1.12.2/series @@ -0,0 +1,7 @@ +# generated by git-ptx-patches +#tag:base --start-number 1 +0001-_dbus_server_new_for_socket-Invalidate-watches-durin.patch +0002-_dbus_server_new_for_socket-Properly-disconnect-duri.patch +0003-_dbus_listen_tcp_socket-Don-t-rely-on-dbus_realloc-s.patch +0004-_dbus_server_new_for_socket-Iterate-over-arrays-as-i.patch +# 25ab7f66637a3a950cd047d33df3f9e5 - git-ptx-patches magic -- 2.15.1 _______________________________________________ ptxdist mailing list ptxdist@pengutronix.de