Skip to content

Commit 369e847

Browse files
committed
Validate size arguments in arraylist functions.
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.
1 parent 2b439ea commit 369e847

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

arraylist.c

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ struct array_list *array_list_new2(array_list_free_fn *free_fn, int initial_size
4545
{
4646
struct array_list *arr;
4747

48+
if (initial_size < 0 || (size_t)initial_size >= SIZE_T_MAX / sizeof(void *))
49+
return NULL;
4850
arr = (struct array_list *)malloc(sizeof(struct array_list));
4951
if (!arr)
5052
return NULL;
@@ -106,6 +108,8 @@ int array_list_shrink(struct array_list *arr, size_t empty_slots)
106108
void *t;
107109
size_t new_size;
108110

111+
if (empty_slots >= SIZE_T_MAX / sizeof(void *) - arr->length)
112+
return -1;
109113
new_size = arr->length + empty_slots;
110114
if (new_size == arr->size)
111115
return 0;

tests/test1.c

+22
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <assert.h>
2+
#include <limits.h>
23
#include <stddef.h>
34
#include <stdio.h>
45
#include <stdlib.h>
@@ -307,6 +308,27 @@ int main(int argc, char **argv)
307308
}
308309
printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object));
309310

311+
json_object_put(my_array);
312+
my_array = json_object_new_array_ext(INT_MIN + 1);
313+
if (my_array != NULL)
314+
{
315+
printf("ERROR: able to allocate an array of negative size!\n");
316+
fflush(stdout);
317+
json_object_put(my_array);
318+
my_array = NULL;
319+
}
320+
321+
#if SIZEOF_SIZE_T == SIZEOF_INT
322+
my_array = json_object_new_array_ext(INT_MAX / 2 + 2);
323+
if (my_array != NULL)
324+
{
325+
printf("ERROR: able to allocate an array of insufficient size!\n");
326+
fflush(stdout);
327+
json_object_put(my_array);
328+
my_array = NULL;
329+
}
330+
#endif
331+
310332
json_object_put(my_string);
311333
json_object_put(my_int);
312334
json_object_put(my_null);

0 commit comments

Comments
 (0)