summaryrefslogtreecommitdiffstats
path: root/debian/patches/sd-bus-enforce-a-size-limit-on-D-Bus-object-paths.patch
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 02:25:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 02:25:51 +0000
commitac8399db6ce846597966360732ce6d39a247bdd2 (patch)
tree046a28d2cbd02afa147291e8f69e9bb5dc29f1aa /debian/patches/sd-bus-enforce-a-size-limit-on-D-Bus-object-paths.patch
parentAdding upstream version 241. (diff)
downloadsystemd-ac8399db6ce846597966360732ce6d39a247bdd2.tar.xz
systemd-ac8399db6ce846597966360732ce6d39a247bdd2.zip
Adding debian version 241-7~deb10u8.debian/241-7_deb10u8
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches/sd-bus-enforce-a-size-limit-on-D-Bus-object-paths.patch')
-rw-r--r--debian/patches/sd-bus-enforce-a-size-limit-on-D-Bus-object-paths.patch215
1 files changed, 215 insertions, 0 deletions
diff --git a/debian/patches/sd-bus-enforce-a-size-limit-on-D-Bus-object-paths.patch b/debian/patches/sd-bus-enforce-a-size-limit-on-D-Bus-object-paths.patch
new file mode 100644
index 0000000..335fccc
--- /dev/null
+++ b/debian/patches/sd-bus-enforce-a-size-limit-on-D-Bus-object-paths.patch
@@ -0,0 +1,215 @@
+From: Martin Pitt <martin@piware.de>
+Date: Sun, 17 Feb 2019 10:17:45 +0100
+Subject: sd-bus: enforce a size limit on D-Bus object paths
+
+Replace stack with heap allocation. This avoids accessing/modifying
+memory outside of the allocated stack region by sending specially
+crafted D-Bus messages with very large object paths.
+
+Vulnerability discovered by Chris Coulson <chris.coulson@canonical.com>,
+patch provided by Riccardo Schirone <rschiron@redhat.com>.
+
+CVE-2019-6454
+---
+ src/libsystemd/sd-bus/bus-internal.c | 2 +-
+ src/libsystemd/sd-bus/bus-internal.h | 4 +++
+ src/libsystemd/sd-bus/bus-objects.c | 64 ++++++++++++++++++++++++++++--------
+ 3 files changed, 55 insertions(+), 15 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c
+index 40acae2..598b7f1 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 f208b29..a8d61bf 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
+
+diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
+index 58329f3..983921d 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,11 @@ 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 +1350,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 +1375,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 +1507,14 @@ 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;
+
+- 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) {
+ n = hashmap_get(bus->nodes, prefix);
+ if (n)
+@@ -2083,8 +2097,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 +2120,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 +2135,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 +2266,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 +2312,11 @@ 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 +2455,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 +2488,11 @@ 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 +2642,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 +2657,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)