diff -Nru systemd-229/debian/changelog systemd-229/debian/changelog --- systemd-229/debian/changelog 2019-01-10 00:15:47.000000000 +0000 +++ systemd-229/debian/changelog 2019-02-13 22:03:22.000000000 +0000 @@ -1,3 +1,17 @@ +systemd (229-4ubuntu21.16) xenial-security; urgency=medium + + * SECURITY UPDATE: denial of service via crafted dbus message + - debian/patches/CVE-2019-6454.patch: sd-bus: enforce a size limit for + dbus paths, and don't allocate them on the stack + - debian/patches/sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch: + sd-bus: if we receive an invalid dbus message, ignore and proceeed + - CVE-2019-6454 + + * Do not remove multiple spaces after identifier in syslog message + - add debian/patches/journal-do-not-remove-multiple-spaces-after-identifi.patch + + -- Chris Coulson Wed, 13 Feb 2019 22:03:22 +0000 + systemd (229-4ubuntu21.15) xenial-security; urgency=medium * SECURITY UPDATE: memory corruption in journald via attacker controlled alloca diff -Nru systemd-229/debian/patches/CVE-2019-6454.patch systemd-229/debian/patches/CVE-2019-6454.patch --- systemd-229/debian/patches/CVE-2019-6454.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-229/debian/patches/CVE-2019-6454.patch 2019-02-13 22:02:40.000000000 +0000 @@ -0,0 +1,199 @@ +Description: sd-bus: enforce a size limit for dbus paths, and don't allocate + them on the stacka +Forwarded: no + +--- 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 -Nru systemd-229/debian/patches/journal-do-not-remove-multiple-spaces-after-identifi.patch systemd-229/debian/patches/journal-do-not-remove-multiple-spaces-after-identifi.patch --- systemd-229/debian/patches/journal-do-not-remove-multiple-spaces-after-identifi.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-229/debian/patches/journal-do-not-remove-multiple-spaces-after-identifi.patch 2019-02-13 22:03:02.000000000 +0000 @@ -0,0 +1,60 @@ +Description: journal: do not remove multiple spaces after identifier in + syslog message +Origin: upstream, https://github.com/systemd/systemd/commit/8595102d3ddde6d25c282f965573a6de34ab4421 + +--- a/src/journal/journald-syslog.c ++++ b/src/journal/journald-syslog.c +@@ -237,7 +237,9 @@ + if (t) + *identifier = t; + +- e += strspn(p + e, WHITESPACE); ++ /* Single space is used as separator */ ++ if (p[e] != '\0' && strchr(WHITESPACE, p[e])) ++ e++; + + *buf = p + e; + return e; +--- a/src/journal/test-journal-syslog.c ++++ b/src/journal/test-journal-syslog.c +@@ -24,7 +24,7 @@ + #include "string-util.h" + + static void test_syslog_parse_identifier(const char *str, +- const char *ident, const char *pid, int ret) { ++ const char *ident, const char *pid, const char *rest, int ret) { + const char *buf = str; + _cleanup_free_ char *ident2 = NULL, *pid2 = NULL; + int ret2; +@@ -34,18 +34,22 @@ + assert_se(ret == ret2); + assert_se(ident == ident2 || streq_ptr(ident, ident2)); + assert_se(pid == pid2 || streq_ptr(pid, pid2)); ++ assert_se(streq(buf, rest)); + } + + int main(void) { +- test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", 11); +- test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 6); +- test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 7); +- test_syslog_parse_identifier("pidu xxx", NULL, NULL, 0); +- test_syslog_parse_identifier(":", "", NULL, 1); +- test_syslog_parse_identifier(": ", "", NULL, 3); +- test_syslog_parse_identifier("pidu:", "pidu", NULL, 5); +- test_syslog_parse_identifier("pidu: ", "pidu", NULL, 6); +- test_syslog_parse_identifier("pidu : ", NULL, NULL, 0); ++ test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", "xxx", 11); ++ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, "xxx", 6); ++ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, " xxx", 6); ++ test_syslog_parse_identifier("pidu xxx", NULL, NULL, "pidu xxx", 0); ++ test_syslog_parse_identifier(" pidu xxx", NULL, NULL, " pidu xxx", 0); ++ test_syslog_parse_identifier("", NULL, NULL, "", 0); ++ test_syslog_parse_identifier(" ", NULL, NULL, " ", 0); ++ test_syslog_parse_identifier(":", "", NULL, "", 1); ++ test_syslog_parse_identifier(": ", "", NULL, " ", 2); ++ test_syslog_parse_identifier("pidu:", "pidu", NULL, "", 5); ++ test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6); ++ test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0); + + return 0; + } diff -Nru systemd-229/debian/patches/sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch systemd-229/debian/patches/sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch --- systemd-229/debian/patches/sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch 1970-01-01 00:00:00.000000000 +0000 +++ systemd-229/debian/patches/sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch 2019-02-13 22:02:55.000000000 +0000 @@ -0,0 +1,50 @@ +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/ + +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 -Nru systemd-229/debian/patches/series systemd-229/debian/patches/series --- systemd-229/debian/patches/series 2019-01-09 15:27:05.000000000 +0000 +++ systemd-229/debian/patches/series 2019-02-13 22:03:20.000000000 +0000 @@ -129,3 +129,6 @@ CVE-2018-16865_1.patch CVE-2018-16865_2.patch CVE-2018-16866.patch +CVE-2019-6454.patch +sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch +journal-do-not-remove-multiple-spaces-after-identifi.patch