From 02fa4a3117396e85f746ba990b44d47306cd5c92 Mon Sep 17 00:00:00 2001 From: George McCollister Date: Mon, 25 Feb 2019 10:37:13 -0600 Subject: systemd: fix CVE-2019-6454 Apply patches from systemd_237-3ubuntu10.13 to fix CVE-2019-6454. CVE-2019-6454 is an issue in which systemd (PID1) can be crashed with a specially formed D-Bus message. For information see: https://usn.ubuntu.com/3891-1/ https://git.launchpad.net/ubuntu/+source/systemd/commit/?h=applied/ubuntu/bionic-updates&id=d7584b894afcaa8a4a1abb69db2a9c81a6276e80 Signed-off-by: George McCollister --- .../systemd/systemd/CVE-2019-6454.patch | 210 +++++++++++++++++++++ ...e-receive-an-invalid-dbus-message-ignore-.patch | 61 ++++++ meta/recipes-core/systemd/systemd_237.bb | 2 + 3 files changed, 273 insertions(+) create mode 100644 meta/recipes-core/systemd/systemd/CVE-2019-6454.patch create mode 100644 meta/recipes-core/systemd/systemd/sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch diff --git a/meta/recipes-core/systemd/systemd/CVE-2019-6454.patch b/meta/recipes-core/systemd/systemd/CVE-2019-6454.patch new file mode 100644 index 0000000000..e3c67c166c --- /dev/null +++ b/meta/recipes-core/systemd/systemd/CVE-2019-6454.patch @@ -0,0 +1,210 @@ +Description: sd-bus: enforce a size limit for dbus paths, and don't allocate + them on the stacka +Forwarded: no + +Patch from: systemd_237-3ubuntu10.13 + +For information see: +https://usn.ubuntu.com/3891-1/ +https://git.launchpad.net/ubuntu/+source/systemd/commit/?h=applied/ubuntu/bionic-updates&id=d7584b894afcaa8a4a1abb69db2a9c81a6276e80 + +CVE: CVE-2019-6454 +Upstream-Status: Backport + +Signed-off-by: George McCollister + +--- a/src/libsystemd/sd-bus/bus-internal.c ++++ b/src/libsystemd/sd-bus/bus-internal.c +@@ -61,7 +61,7 @@ + if (slash) + return false; + +- return true; ++ return (q - p) <= BUS_PATH_SIZE_MAX; + } + + char* object_path_startswith(const char *a, const char *b) { +--- a/src/libsystemd/sd-bus/bus-internal.h ++++ b/src/libsystemd/sd-bus/bus-internal.h +@@ -339,6 +339,10 @@ + + #define BUS_MESSAGE_SIZE_MAX (64*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 + +--- a/src/libsystemd/sd-bus/bus-objects.c ++++ b/src/libsystemd/sd-bus/bus-objects.c +@@ -1150,7 +1150,8 @@ + const char *path, + sd_bus_error *error) { + +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; + int r; + + assert(bus); +@@ -1166,7 +1167,12 @@ + 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) +@@ -1362,6 +1368,7 @@ + } + + 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; +@@ -1386,9 +1393,12 @@ + 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); +@@ -1516,9 +1526,15 @@ + + 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) +@@ -2108,8 +2124,9 @@ + char **names) { + + BUS_DONT_DESTROY(bus); ++ _cleanup_free_ char *prefix = NULL; + bool found_interface = false; +- char *prefix; ++ size_t pl; + int r; + + assert_return(bus, -EINVAL); +@@ -2128,6 +2145,12 @@ + 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; + +@@ -2137,7 +2160,6 @@ + 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) +@@ -2269,7 +2291,8 @@ + + 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); +@@ -2314,7 +2337,12 @@ + 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) +@@ -2453,7 +2481,8 @@ + + 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); +@@ -2485,7 +2514,12 @@ + 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) +@@ -2635,7 +2669,8 @@ + const char *path, + const char *interface) { + +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; + int r; + + assert(bus); +@@ -2649,7 +2684,12 @@ + 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/meta/recipes-core/systemd/systemd/sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch b/meta/recipes-core/systemd/systemd/sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch new file mode 100644 index 0000000000..4ffa739145 --- /dev/null +++ b/meta/recipes-core/systemd/systemd/sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch @@ -0,0 +1,61 @@ +Description: 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. +Author: Lennart Poettering +Forwarded: other,https://github.com/systemd/systemd/pull/11708/ + +Patch from: systemd_237-3ubuntu10.13 + +For information see: +https://usn.ubuntu.com/3891-1/ +https://git.launchpad.net/ubuntu/+source/systemd/commit/?h=applied/ubuntu/bionic-updates&id=d7584b894afcaa8a4a1abb69db2a9c81a6276e80 + +CVE: CVE-2019-6454 +Upstream-Status: Backport + +Signed-off-by: George McCollister + +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.17.1 + diff --git a/meta/recipes-core/systemd/systemd_237.bb b/meta/recipes-core/systemd/systemd_237.bb index bc33fbebdc..a0e5d512e0 100644 --- a/meta/recipes-core/systemd/systemd_237.bb +++ b/meta/recipes-core/systemd/systemd_237.bb @@ -63,6 +63,8 @@ SRC_URI += "file://touchscreen.rules \ file://0027-journal-fix-out-of-bounds-read-CVE-2018-16866.patch \ file://0001-tmpfiles-don-t-resolve-pathnames-when-traversing-rec.patch \ file://0002-Make-tmpfiles-safe.patch \ + file://CVE-2019-6454.patch \ + file://sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch \ " SRC_URI_append_qemuall = " file://0001-core-device.c-Change-the-default-device-timeout-to-2.patch" -- cgit 1.2.3-korg