diff --git a/SOURCES/0091-bus-socket-Fix-line_begins-to-accept-word-matching-f.patch b/SOURCES/0091-bus-socket-Fix-line_begins-to-accept-word-matching-f.patch new file mode 100644 index 0000000..2c399e3 --- /dev/null +++ b/SOURCES/0091-bus-socket-Fix-line_begins-to-accept-word-matching-f.patch @@ -0,0 +1,48 @@ +From cce8d42c8d86167f22c86c226383a40dea28388a Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Tue, 17 Jul 2018 11:32:40 -0700 +Subject: [PATCH] bus-socket: Fix line_begins() to accept word matching full + string + +The switch to memory_startswith() changed the logic to only look for a space or +NUL byte after the matched word, but matching the full size should also be +acceptable. + +This changed the behavior of parsing of "AUTH\r\n", where m will be set to 4, +since even though the word will match, the check for it being followed by ' ' +or NUL will make line_begins() return false. + +Tested: + +- Using netcat to connect to the private socket directly: + $ echo -ne '\0AUTH\r\n' | sudo nc -U /run/systemd/private + REJECTED EXTERNAL ANONYMOUS + +- Running the Ignition blackbox test: + $ sudo sh -c 'PATH=$PWD/bin/amd64:$PATH ./tests.test' + PASS + +Fixes: d27b725abf64a19a6b2f99332b663f17ad046771 +(cherry picked from commit 3f10c66270b74530339b3f466c43874bb40c210f) + +Resolves: #1692991 +--- + src/libsystemd/sd-bus/bus-socket.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index b147a3843..a5513d1ab 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -248,10 +248,7 @@ static bool line_begins(const char *s, size_t m, const char *word) { + const char *p; + + p = memory_startswith(s, m, word); +- if (!p) +- return false; +- +- return IN_SET(*p, 0, ' '); ++ return p && (p == (s + m) || *p == ' '); + } + + static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) { diff --git a/SOURCES/0092-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch b/SOURCES/0092-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch new file mode 100644 index 0000000..4bbb89d --- /dev/null +++ b/SOURCES/0092-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch @@ -0,0 +1,49 @@ +From 9c2246f25010b9657b765c546c0e278d4824ab2c 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. + +(cherry-picked from commit 61397a60d98e368a5720b37e83f3169e3eb511c4) + +Related: #1678641 +--- + 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 7bb653338..35e0b668e 100644 +--- a/src/libsystemd/sd-bus/bus-internal.c ++++ b/src/libsystemd/sd-bus/bus-internal.c +@@ -45,7 +45,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 2087ef8ee..90e602898 100644 +--- a/src/libsystemd/sd-bus/bus-internal.h ++++ b/src/libsystemd/sd-bus/bus-internal.h +@@ -333,6 +333,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/0093-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch b/SOURCES/0093-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch new file mode 100644 index 0000000..a200942 --- /dev/null +++ b/SOURCES/0093-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch @@ -0,0 +1,189 @@ +From 268f983d2a9e093f1d432f4c530ed51f08f14870 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. + +(cherry-picked from commit f519a19bcd5afe674a9b8fc462cd77d8bad403c1) + +Related: #1678641 +--- + src/libsystemd/sd-bus/bus-objects.c | 68 +++++++++++++++++++++++------ + 1 file changed, 54 insertions(+), 14 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c +index a18ff88b0..53bf0fd62 100644 +--- a/src/libsystemd/sd-bus/bus-objects.c ++++ b/src/libsystemd/sd-bus/bus-objects.c +@@ -1134,7 +1134,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); +@@ -1150,7 +1151,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) +@@ -1346,6 +1352,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; +@@ -1370,9 +1377,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); +@@ -1499,9 +1509,15 @@ static int bus_find_parent_object_manager(sd_bus *bus, struct node **out, const + + n = hashmap_get(bus->nodes, path); + if (!n) { +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; ++ ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; + +- prefix = alloca(strlen(path) + 1); + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + n = hashmap_get(bus->nodes, prefix); + if (n) +@@ -2090,8 +2106,9 @@ _public_ int sd_bus_emit_properties_changed_strv( + const char *interface, + char **names) { + ++ _cleanup_free_ char *prefix = NULL; + bool found_interface = false; +- char *prefix; ++ size_t pl; + int r; + + assert_return(bus, -EINVAL); +@@ -2112,6 +2129,12 @@ _public_ int sd_bus_emit_properties_changed_strv( + + BUS_DONT_DESTROY(bus); + ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + do { + bus->nodes_modified = false; + +@@ -2121,7 +2144,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) +@@ -2253,7 +2275,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); +@@ -2298,7 +2321,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) +@@ -2437,7 +2465,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); +@@ -2469,7 +2498,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) +@@ -2619,7 +2653,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); +@@ -2633,7 +2668,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/0094-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch b/SOURCES/0094-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch new file mode 100644 index 0000000..e3038e1 --- /dev/null +++ b/SOURCES/0094-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch @@ -0,0 +1,55 @@ +From 4573166e9384f4ffe17a87f7b41aacc4cfe8bad0 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: #1678641 +--- + 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 a5513d1ab..17cfa8e1f 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -1078,7 +1078,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; + +@@ -1103,7 +1103,9 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) { + bus->fds, bus->n_fds, + 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; + } +@@ -1114,7 +1116,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 f8573fa..ae8d934 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 13%{?dist} +Release: 13%{?dist}.3 # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -140,6 +140,10 @@ Patch0087: 0087-test-replace-echo-with-socat.patch Patch0088: 0088-test-network-ignore-tunnel-devices-automatically-add.patch Patch0089: 0089-rules-add-elevator-kernel-command-line-parameter.patch Patch0090: 0090-rules-add-the-rule-that-adds-elevator-kernel-command.patch +Patch0091: 0091-bus-socket-Fix-line_begins-to-accept-word-matching-f.patch +Patch0092: 0092-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch +Patch0093: 0093-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch +Patch0094: 0094-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch %ifarch %{ix86} x86_64 aarch64 @@ -759,6 +763,17 @@ fi %files tests -f .file-list-tests %changelog +* Tue Apr 09 2019 Lukas Nykryn - 239-13.3 +- rebuilt + +* Mon Apr 08 2019 Lukas Nykryn - 239-13.2 +- Refuse dbus message paths longer than BUS_PATH_SIZE_MAX limit. (#1678641) +- Allocate temporary strings to hold dbus paths on the heap (#1678641) +- sd-bus: if we receive an invalid dbus message, ignore and proceeed (#1678641) + +* Thu Mar 28 2019 Lukas Nykryn - 239-13.1 +- bus-socket: Fix line_begins() to accept word matching full string (#1692991) + * Tue Feb 26 2019 Lukas Nykryn - 239-13 - rules: add the rule that adds elevator= kernel command line parameter (#1670126)