bus-message: avoid wrap-around when using length read from message
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 23 Aug 2018 12:48:40 +0000 (14:48 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 2 Oct 2018 09:59:08 +0000 (11:59 +0200)
We would read (-1), and then add 1 to it, call message_peek_body(..., 0, ...),
and when trying to make use of the data.

The fuzzer test case is just for one site, but they all look similar.

v2: fix two UINT8_MAX/UINT32_MAX mismatches founds by LGTM

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

index a484dc4..697553e 100644 (file)
@@ -3389,6 +3389,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
                                 return r;
 
                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
+                        if (l == UINT32_MAX)
+                                /* avoid overflow right below */
+                                return -EBADMSG;
+
                         r = message_peek_body(m, &rindex, 1, l+1, &q);
                         if (r < 0)
                                 return r;
@@ -3411,6 +3415,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
                                 return r;
 
                         l = *(uint8_t*) q;
+                        if (l == UINT8_MAX)
+                                /* avoid overflow right below */
+                                return -EBADMSG;
+
                         r = message_peek_body(m, &rindex, 1, l+1, &q);
                         if (r < 0)
                                 return r;
@@ -3676,6 +3684,10 @@ static int bus_message_enter_variant(
                         return r;
 
                 l = *(uint8_t*) q;
+                if (l == UINT8_MAX)
+                        /* avoid overflow right below */
+                        return -EBADMSG;
+
                 r = message_peek_body(m, &rindex, 1, l+1, &q);
                 if (r < 0)
                         return r;
@@ -4244,6 +4256,10 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
                                         return r;
 
                                 l = *(uint8_t*) q;
+                                if (l == UINT8_MAX)
+                                        /* avoid overflow right below */
+                                        return -EBADMSG;
+
                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
                                 if (r < 0)
                                         return r;
@@ -4826,6 +4842,10 @@ static int message_peek_field_string(
                 if (r < 0)
                         return r;
 
+                if (l == UINT32_MAX)
+                        /* avoid overflow right below */
+                        return -EBADMSG;
+
                 r = message_peek_fields(m, ri, 1, l+1, &q);
                 if (r < 0)
                         return r;
@@ -4877,6 +4897,10 @@ static int message_peek_field_signature(
                         return r;
 
                 l = *(uint8_t*) q;
+                if (l == UINT8_MAX)
+                        /* avoid overflow right below */
+                        return -EBADMSG;
+
                 r = message_peek_fields(m, ri, 1, l+1, &q);
                 if (r < 0)
                         return r;
diff --git a/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36 b/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36
new file mode 100644 (file)
index 0000000..b3fee9e
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36 differ