summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gilbert <floppym@gentoo.org>2019-02-17 13:31:37 -0500
committerMike Gilbert <floppym@gentoo.org>2019-02-18 18:31:56 -0500
commitc0e6ffa5671fad0b3830348ff960b8ec4e3d2f27 (patch)
treeef848494eb2164e9effe11175c84842559c73057 /sys-apps/systemd/files
parenteclass: Fix kernel dependency for gcc v8 patch in kernel-2.eclass (diff)
downloadgentoo-c0e6ffa5671fad0b3830348ff960b8ec4e3d2f27.tar.gz
gentoo-c0e6ffa5671fad0b3830348ff960b8ec4e3d2f27.tar.bz2
gentoo-c0e6ffa5671fad0b3830348ff960b8ec4e3d2f27.zip
sys-apps/systemd: backport patches for CVE-2019-6454
Bug: https://bugs.gentoo.org/677944 Package-Manager: Portage-2.3.59_p2, Repoman-2.3.12_p67 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
Diffstat (limited to 'sys-apps/systemd/files')
-rw-r--r--sys-apps/systemd/files/CVE-2019-6454/0001-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch48
-rw-r--r--sys-apps/systemd/files/CVE-2019-6454/0002-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch188
-rw-r--r--sys-apps/systemd/files/CVE-2019-6454/0003-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch54
3 files changed, 290 insertions, 0 deletions
diff --git a/sys-apps/systemd/files/CVE-2019-6454/0001-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch b/sys-apps/systemd/files/CVE-2019-6454/0001-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch
new file mode 100644
index 000000000000..6a0c8d1b0c51
--- /dev/null
+++ b/sys-apps/systemd/files/CVE-2019-6454/0001-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch
@@ -0,0 +1,48 @@
+From 29de632674473729d1e9497b6fe47e7c88682ed9 Mon Sep 17 00:00:00 2001
+From: Riccardo Schirone <rschiron@redhat.com>
+Date: Mon, 4 Feb 2019 14:29:09 +0100
+Subject: [PATCH 1/3] 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.
+---
+ 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 40acae2133..598b7f110c 100644
+--- a/src/libsystemd/sd-bus/bus-internal.c
++++ b/src/libsystemd/sd-bus/bus-internal.c
+@@ -43,7 +43,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 f208b294d8..a8d61bf72a 100644
+--- a/src/libsystemd/sd-bus/bus-internal.h
++++ b/src/libsystemd/sd-bus/bus-internal.h
+@@ -332,6 +332,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
+
+--
+2.20.1
+
diff --git a/sys-apps/systemd/files/CVE-2019-6454/0002-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch b/sys-apps/systemd/files/CVE-2019-6454/0002-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch
new file mode 100644
index 000000000000..bbc6db974d4a
--- /dev/null
+++ b/sys-apps/systemd/files/CVE-2019-6454/0002-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch
@@ -0,0 +1,188 @@
+From 1ffe59592c5cbf924eb81a3662b4252ba6de7132 Mon Sep 17 00:00:00 2001
+From: Riccardo Schirone <rschiron@redhat.com>
+Date: Mon, 4 Feb 2019 14:29:28 +0100
+Subject: [PATCH 2/3] 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.
+---
+ 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 58329f3fe7..54b977418e 100644
+--- a/src/libsystemd/sd-bus/bus-objects.c
++++ b/src/libsystemd/sd-bus/bus-objects.c
+@@ -1133,7 +1133,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);
+@@ -1149,7 +1150,12 @@ static int object_manager_serialize_path_and_fallbacks(
+ return 0;
+
+ /* Second, add fallback vtables registered for any of the prefixes */
+- prefix = newa(char, 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)
+@@ -1345,6 +1351,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;
+@@ -1369,9 +1376,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);
+@@ -1498,9 +1508,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 = newa(char, strlen(path) + 1);
+ OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
+ n = hashmap_get(bus->nodes, prefix);
+ if (n)
+@@ -2083,8 +2099,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);
+@@ -2105,6 +2122,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;
+
+@@ -2114,7 +2137,6 @@ _public_ int sd_bus_emit_properties_changed_strv(
+ if (bus->nodes_modified)
+ continue;
+
+- prefix = newa(char, 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)
+@@ -2246,7 +2268,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);
+@@ -2291,7 +2314,12 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p
+ if (bus->nodes_modified)
+ return 0;
+
+- prefix = newa(char, 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)
+@@ -2430,7 +2458,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);
+@@ -2462,7 +2491,12 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char
+ if (bus->nodes_modified)
+ return 0;
+
+- prefix = newa(char, 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)
+@@ -2612,7 +2646,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);
+@@ -2626,7 +2661,12 @@ static int interfaces_added_append_one(
+ if (bus->nodes_modified)
+ return 0;
+
+- prefix = newa(char, 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)
+--
+2.20.1
+
diff --git a/sys-apps/systemd/files/CVE-2019-6454/0003-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch b/sys-apps/systemd/files/CVE-2019-6454/0003-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch
new file mode 100644
index 000000000000..cc03893a588d
--- /dev/null
+++ b/sys-apps/systemd/files/CVE-2019-6454/0003-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch
@@ -0,0 +1,54 @@
+From 8d3cea620ab661897fb485ece7332a9073c1783d Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Wed, 13 Feb 2019 16:51:22 +0100
+Subject: [PATCH 3/3] 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.
+---
+ 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 30d6455b6f..441b4a816f 100644
+--- a/src/libsystemd/sd-bus/bus-socket.c
++++ b/src/libsystemd/sd-bus/bus-socket.c
+@@ -1072,7 +1072,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;
+
+@@ -1097,7 +1097,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;
+ }
+@@ -1108,7 +1110,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;
+ }
+--
+2.20.1
+