bus-message: fix calculation of offsets table for arrays
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 3 Aug 2018 12:46:57 +0000 (14:46 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 2 Oct 2018 09:53:20 +0000 (11:53 +0200)
This is similar to the grandparent commit 'fix calculation of offsets table',
except that now the change is for array elements. Same story as before: we need
to make sure that the offsets increase enough taking alignment into account.

While at it, rename 'p' to 'previous' to match similar code in other places.

src/libsystemd/sd-bus/bus-message.c
test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5 [new file with mode: 0644]

index 11b050a..f544ec1 100644 (file)
@@ -3507,7 +3507,7 @@ static int bus_message_enter_array(
 
         size_t rindex;
         void *q;
-        int r, alignment;
+        int r;
 
         assert(m);
         assert(c);
@@ -3533,6 +3533,7 @@ static int bus_message_enter_array(
 
         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
                 /* dbus1 */
+                int alignment;
 
                 r = message_peek_body(m, &rindex, 4, 4, &q);
                 if (r < 0)
@@ -3566,7 +3567,8 @@ static int bus_message_enter_array(
                 *n_offsets = 0;
 
         } else {
-                size_t where, p = 0, framing, sz;
+                size_t where, previous = 0, framing, sz;
+                int alignment;
                 unsigned i;
 
                 /* gvariant: variable length array */
@@ -3594,17 +3596,22 @@ static int bus_message_enter_array(
                 if (!*offsets)
                         return -ENOMEM;
 
+                alignment = bus_gvariant_get_alignment(c->signature);
+                assert(alignment > 0);
+
                 for (i = 0; i < *n_offsets; i++) {
-                        size_t x;
+                        size_t x, start;
+
+                        start = ALIGN_TO(previous, alignment);
 
                         x = bus_gvariant_read_word_le((uint8_t*) q + i * sz, sz);
                         if (x > c->item_size - sz)
                                 return -EBADMSG;
-                        if (x < p)
+                        if (x < start)
                                 return -EBADMSG;
 
                         (*offsets)[i] = rindex + x;
-                        p = x;
+                        previous = x;
                 }
 
                 *item_size = (*offsets)[0] - rindex;
diff --git a/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5 b/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5
new file mode 100644 (file)
index 0000000..26262e1
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5 differ