]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: fix buffer overflow
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 26 May 2022 19:23:10 +0000 (04:23 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 28 May 2022 08:06:14 +0000 (10:06 +0200)
Fixes #23486.

src/libsystemd/sd-bus/bus-message.c
test/fuzz/fuzz-bus-message/issue-23486-case-1 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/issue-23486-case-2 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/issue-23486-case-3 [new file with mode: 0644]

index b77372c3a07d5a83a99b2a2375a2fa5c97f95beb..026ec101e3a5ff5633aa68465c989be27e759444 100644 (file)
@@ -428,7 +428,7 @@ int bus_message_from_header(
 
         _cleanup_free_ sd_bus_message *m = NULL;
         struct bus_header *h;
-        size_t a, label_sz;
+        size_t a, label_sz = 0; /* avoid false maybe-uninitialized warning */
 
         assert(bus);
         assert(header || header_accessible <= 0);
@@ -506,7 +506,10 @@ int bus_message_from_header(
                 m->fields_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.fields_size);
                 m->body_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.body_size);
 
-                if (sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size != message_size)
+                assert(message_size >= sizeof(struct bus_header));
+                if (m->fields_size > message_size - sizeof(struct bus_header) ||
+                    ALIGN8(m->fields_size) > message_size - sizeof(struct bus_header) ||
+                    m->body_size != message_size - sizeof(struct bus_header) - ALIGN8(m->fields_size))
                         return -EBADMSG;
         }
 
@@ -3061,15 +3064,21 @@ void bus_body_part_unmap(struct bus_body_part *part) {
         return;
 }
 
-static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
+static int buffer_peek(const void *p, size_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
         size_t k, start, end;
 
         assert(rindex);
         assert(align > 0);
 
-        start = ALIGN_TO((size_t) *rindex, align);
-        end = start + nbytes;
+        start = ALIGN_TO(*rindex, align);
+        if (start > sz)
+                return -EBADMSG;
+
+        /* Avoid overflow below */
+        if (nbytes > SIZE_MAX - start)
+                return -EBADMSG;
 
+        end = start + nbytes;
         if (end > sz)
                 return -EBADMSG;
 
@@ -3272,10 +3281,17 @@ static int message_peek_body(
         assert(rindex);
         assert(align > 0);
 
-        start = ALIGN_TO((size_t) *rindex, align);
+        start = ALIGN_TO(*rindex, align);
+        if (start > m->user_body_size)
+                return -EBADMSG;
+
         padding = start - *rindex;
-        end = start + nbytes;
 
+        /* Avoid overflow below */
+        if (nbytes > SIZE_MAX - start)
+                return -EBADMSG;
+
+        end = start + nbytes;
         if (end > m->user_body_size)
                 return -EBADMSG;
 
diff --git a/test/fuzz/fuzz-bus-message/issue-23486-case-1 b/test/fuzz/fuzz-bus-message/issue-23486-case-1
new file mode 100644 (file)
index 0000000..fe8338b
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/issue-23486-case-1 differ
diff --git a/test/fuzz/fuzz-bus-message/issue-23486-case-2 b/test/fuzz/fuzz-bus-message/issue-23486-case-2
new file mode 100644 (file)
index 0000000..1791244
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/issue-23486-case-2 differ
diff --git a/test/fuzz/fuzz-bus-message/issue-23486-case-3 b/test/fuzz/fuzz-bus-message/issue-23486-case-3
new file mode 100644 (file)
index 0000000..cff8b38
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/issue-23486-case-3 differ