diff --git a/SOURCES/0670-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch b/SOURCES/0670-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch new file mode 100644 index 0000000..0053542 --- /dev/null +++ b/SOURCES/0670-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch @@ -0,0 +1,47 @@ +From dfb87e5916ce13e75af2cefd62bbbafaef143d8c Mon Sep 17 00:00:00 2001 +From: Riccardo Schirone +Date: Mon, 4 Feb 2019 14:29:09 +0100 +Subject: [PATCH] Refuse dbus message paths longer than BUS_PATH_SIZE_MAX + limit. + +Even though the dbus specification does not enforce any length limit on the +path of a dbus message, having to analyze too long strings in PID1 may be +time-consuming and it may have security impacts. + +In any case, the limit is set so high that real-life applications should not +have a problem with it. + +Related: #1667870 +--- + src/libsystemd/sd-bus/bus-internal.c | 2 +- + src/libsystemd/sd-bus/bus-internal.h | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c +index 91b288cd2..c952d63e1 100644 +--- a/src/libsystemd/sd-bus/bus-internal.c ++++ b/src/libsystemd/sd-bus/bus-internal.c +@@ -58,7 +58,7 @@ bool object_path_is_valid(const char *p) { + if (slash) + return false; + +- return true; ++ return (q - p) <= BUS_PATH_SIZE_MAX; + } + + char* object_path_startswith(const char *a, const char *b) { +diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h +index 9c1e5a35b..1c5fbeac2 100644 +--- a/src/libsystemd/sd-bus/bus-internal.h ++++ b/src/libsystemd/sd-bus/bus-internal.h +@@ -331,6 +331,10 @@ struct sd_bus { + + #define BUS_MESSAGE_SIZE_MAX (128*1024*1024) + #define BUS_AUTH_SIZE_MAX (64*1024) ++/* Note that the D-Bus specification states that bus paths shall have no size limit. We enforce here one ++ * anyway, since truly unbounded strings are a security problem. The limit we pick is relatively large however, ++ * to not clash unnecessarily with real-life applications. */ ++#define BUS_PATH_SIZE_MAX (64*1024) + + #define BUS_CONTAINER_DEPTH 128 + diff --git a/SOURCES/0671-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch b/SOURCES/0671-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch new file mode 100644 index 0000000..8cbe0fb --- /dev/null +++ b/SOURCES/0671-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch @@ -0,0 +1,170 @@ +From f0ee84481e7dd822fb5864de3e46c8d85400ee8e Mon Sep 17 00:00:00 2001 +From: Riccardo Schirone +Date: Mon, 4 Feb 2019 14:29:28 +0100 +Subject: [PATCH] Allocate temporary strings to hold dbus paths on the heap + +Paths are limited to BUS_PATH_SIZE_MAX but the maximum size is anyway too big +to be allocated on the stack, so let's switch to the heap where there is a +clear way to understand if the allocation fails. + +Resolves: #1667870 +--- + src/libsystemd/sd-bus/bus-objects.c | 58 +++++++++++++++++++++++------ + 1 file changed, 46 insertions(+), 12 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c +index fc6c22328..8df73bdf4 100644 +--- a/src/libsystemd/sd-bus/bus-objects.c ++++ b/src/libsystemd/sd-bus/bus-objects.c +@@ -1104,7 +1104,8 @@ static int object_manager_serialize_path_and_fallbacks( + const char *path, + sd_bus_error *error) { + +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; + int r; + + assert(bus); +@@ -1120,7 +1121,12 @@ static int object_manager_serialize_path_and_fallbacks( + return 0; + + /* Second, add fallback vtables registered for any of the prefixes */ +- prefix = alloca(strlen(path) + 1); ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + r = object_manager_serialize_path(bus, reply, prefix, path, true, error); + if (r < 0) +@@ -1316,6 +1322,7 @@ static int object_find_and_run( + } + + int bus_process_object(sd_bus *bus, sd_bus_message *m) { ++ _cleanup_free_ char *prefix = NULL; + int r; + size_t pl; + bool found_object = false; +@@ -1340,9 +1347,12 @@ int bus_process_object(sd_bus *bus, sd_bus_message *m) { + assert(m->member); + + pl = strlen(m->path); +- do { +- char prefix[pl+1]; ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; + ++ do { + bus->nodes_modified = false; + + r = object_find_and_run(bus, m, m->path, false, &found_object); +@@ -2044,9 +2054,10 @@ _public_ int sd_bus_emit_properties_changed_strv( + const char *interface, + char **names) { + ++ _cleanup_free_ char *prefix = NULL; + BUS_DONT_DESTROY(bus); + bool found_interface = false; +- char *prefix; ++ size_t pl; + int r; + + assert_return(bus, -EINVAL); +@@ -2064,6 +2075,12 @@ _public_ int sd_bus_emit_properties_changed_strv( + if (names && names[0] == NULL) + return 0; + ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + do { + bus->nodes_modified = false; + +@@ -2073,7 +2090,6 @@ _public_ int sd_bus_emit_properties_changed_strv( + if (bus->nodes_modified) + continue; + +- prefix = alloca(strlen(path) + 1); + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + r = emit_properties_changed_on_interface(bus, prefix, path, interface, true, &found_interface, names); + if (r != 0) +@@ -2204,7 +2220,8 @@ static int object_added_append_all_prefix( + + static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *path) { + _cleanup_set_free_ Set *s = NULL; +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; + int r; + + assert(bus); +@@ -2249,7 +2266,12 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p + if (bus->nodes_modified) + return 0; + +- prefix = alloca(strlen(path) + 1); ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + r = object_added_append_all_prefix(bus, m, s, prefix, path, true); + if (r < 0) +@@ -2380,7 +2402,8 @@ static int object_removed_append_all_prefix( + + static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char *path) { + _cleanup_set_free_ Set *s = NULL; +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; + int r; + + assert(bus); +@@ -2412,7 +2435,12 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char + if (bus->nodes_modified) + return 0; + +- prefix = alloca(strlen(path) + 1); ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + r = object_removed_append_all_prefix(bus, m, s, prefix, path, true); + if (r < 0) +@@ -2554,7 +2582,8 @@ static int interfaces_added_append_one( + const char *path, + const char *interface) { + +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; + int r; + + assert(bus); +@@ -2568,7 +2597,12 @@ static int interfaces_added_append_one( + if (bus->nodes_modified) + return 0; + +- prefix = alloca(strlen(path) + 1); ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + r = interfaces_added_append_one_prefix(bus, m, prefix, path, interface, true); + if (r != 0) diff --git a/SOURCES/0672-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch b/SOURCES/0672-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch new file mode 100644 index 0000000..b2d2bbc --- /dev/null +++ b/SOURCES/0672-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch @@ -0,0 +1,55 @@ +From f2126dbc1dcaca92250427e76e7a87e61b10f540 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 13 Feb 2019 16:51:22 +0100 +Subject: [PATCH] sd-bus: if we receive an invalid dbus message, ignore and + proceeed + +dbus-daemon might have a slightly different idea of what a valid msg is +than us (for example regarding valid msg and field sizes). Let's hence +try to proceed if we can and thus drop messages rather than fail the +connection if we fail to validate a message. + +Hopefully the differences in what is considered valid are not visible +for real-life usecases, but are specific to exploit attempts only. + +(cherry-picked from commit 6d586a13717ae057aa1b4127400c3de61cd5b9e7) + +Related: #1667871 +--- + src/libsystemd/sd-bus/bus-socket.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index ab56ef4f3..4437024bb 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -879,7 +879,7 @@ static int bus_socket_read_message_need(sd_bus *bus, size_t *need) { + } + + static int bus_socket_make_message(sd_bus *bus, size_t size) { +- sd_bus_message *t; ++ sd_bus_message *t = NULL; + void *b; + int r; + +@@ -905,7 +905,9 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) { + NULL, + NULL, + &t); +- if (r < 0) { ++ if (r == -EBADMSG) ++ log_debug_errno(r, "Received invalid message from connection %s, dropping.", strna(bus->description)); ++ else if (r < 0) { + free(b); + return r; + } +@@ -916,7 +918,8 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) { + bus->fds = NULL; + bus->n_fds = 0; + +- bus->rqueue[bus->rqueue_size++] = t; ++ if (t) ++ bus->rqueue[bus->rqueue_size++] = t; + + return 1; + } diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index c8953f6..87a66cc 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -7,7 +7,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 219 -Release: 62%{?dist}.3 +Release: 62%{?dist}.5 # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: A System and Service Manager @@ -708,6 +708,9 @@ Patch0666: 0666-journald-do-not-store-the-iovec-entry-for-process-co.patch Patch0667: 0667-journald-set-a-limit-on-the-number-of-fields-1k.patch Patch0668: 0668-journal-remote-set-a-limit-on-the-number-of-fields-i.patch Patch0669: 0669-journald-free-cmdline-buffers-owned-by-iovec.patch +Patch0670: 0670-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch +Patch0671: 0671-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch +Patch0672: 0672-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} @@ -1684,6 +1687,13 @@ fi %{_mandir}/man8/systemd-resolved.* %changelog +* Thu Feb 14 2019 Lukas Nykryn - 219-62.5 +- sd-bus: if we receive an invalid dbus message, ignore and proceeed (#1667871) + +* Thu Feb 07 2019 Lukas Nykryn - 219-62.4 +- Refuse dbus message paths longer than BUS_PATH_SIZE_MAX limit. (#1667870) +- Allocate temporary strings to hold dbus paths on the heap (#1667870) + * Wed Jan 16 2019 Lukas Nykryn - 219-62.3 - journald: free cmdline buffers owned by iovec (#1666646)