]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
Validate size arguments in arraylist functions. 660/head
authorTobias Stoeckmann <tobias@stoeckmann.org>
Sat, 22 Aug 2020 10:06:15 +0000 (12:06 +0200)
committerTobias Stoeckmann <tobias@stoeckmann.org>
Mon, 24 Aug 2020 10:13:50 +0000 (12:13 +0200)
The array_list_new2 function, which is externally reachable through
json_object_new_array_ext, does not check if specified initial size
actually fits into memory on 32 bit architectures.

It also allows negative values, which could lead to an overflow on these
architectures as well. I have added test cases for these situations.

While at it, also protect array_list_shrink against too large
empty_slots argument. No test added because it takes a huge length
value, therefore a lot of items within the array, to overflow the
calculation. In theory this affects 64 bit sytems as well, but since the
arraylist API is not supposed to be used by external applications
according to its header file, the call is protected due to int
limitation of json_object_array_shrink.

arraylist.c
tests/test1.c

index c21b8e1dfb3c0744aa740618c982aadd958114ed..d8e12d11cbc77a7a029cc02dad2be0f3469875cd 100644 (file)
@@ -45,6 +45,8 @@ struct array_list *array_list_new2(array_list_free_fn *free_fn, int initial_size
 {
        struct array_list *arr;
 
+       if (initial_size < 0 || (size_t)initial_size >= SIZE_T_MAX / sizeof(void *))
+               return NULL;
        arr = (struct array_list *)malloc(sizeof(struct array_list));
        if (!arr)
                return NULL;
@@ -106,6 +108,8 @@ int array_list_shrink(struct array_list *arr, size_t empty_slots)
        void *t;
        size_t new_size;
 
+       if (empty_slots >= SIZE_T_MAX / sizeof(void *) - arr->length)
+               return -1;
        new_size = arr->length + empty_slots;
        if (new_size == arr->size)
                return 0;
index 6682120cd948e21484bba1cbdc846ff3a3d0995b..7e416105610ac1820c653c6a7c15c0e06c513202 100644 (file)
@@ -1,4 +1,5 @@
 #include <assert.h>
+#include <limits.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -307,6 +308,27 @@ int main(int argc, char **argv)
        }
        printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object));
 
+       json_object_put(my_array);
+       my_array = json_object_new_array_ext(INT_MIN + 1);
+       if (my_array != NULL)
+       {
+               printf("ERROR: able to allocate an array of negative size!\n");
+               fflush(stdout);
+               json_object_put(my_array);
+               my_array = NULL;
+       }
+
+#if SIZEOF_SIZE_T == SIZEOF_INT
+       my_array = json_object_new_array_ext(INT_MAX / 2 + 2);
+       if (my_array != NULL)
+       {
+               printf("ERROR: able to allocate an array of insufficient size!\n");
+               fflush(stdout);
+               json_object_put(my_array);
+               my_array = NULL;
+       }
+#endif
+
        json_object_put(my_string);
        json_object_put(my_int);
        json_object_put(my_null);