1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
Origin: backport, https://github.com/DaveGamble/cJSON/commit/60ff122ef5862d04b39b150541459e7f5e35add8
From: Peter Alfred Lee <peterlee@apache.com>
Bug: https://github.com/DaveGamble/cJSON/issues/803
Bug: https://github.com/DaveGamble/cJSON/issues/802
Bug-Debian: https://bugs.debian.org/1059287
Acked-by: Maytham Alsudany <maytha8thedev@gmail.com>
Subject: [PATCH] add NULL checkings (#809)
* add NULL checks in cJSON_SetValuestring
Fixes #803(CVE-2023-50472)
.
* add NULL check in cJSON_InsertItemInArray
Fixes #802(CVE-2023-50471)
.
* add tests for NULL checks
add tests for NULL checks in cJSON_InsertItemInArray and cJSON_SetValuestring
--- a/cJSON.c
+++ b/cJSON.c
@@ -401,7 +401,12 @@
{
char *copy = NULL;
/* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
- if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference))
+ if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference))
+ {
+ return NULL;
+ }
+ /* return NULL if the object is corrupted */
+ if (object->valuestring == NULL)
{
return NULL;
}
@@ -2260,7 +2265,7 @@
{
cJSON *after_inserted = NULL;
- if (which < 0)
+ if (which < 0 || newitem == NULL)
{
return false;
}
@@ -2271,6 +2276,11 @@
return add_item_to_array(array, newitem);
}
+ if (after_inserted != array->child && newitem->prev == NULL) {
+ /* return false if after_inserted is a corrupted array item */
+ return false;
+ }
+
newitem->next = after_inserted;
newitem->prev = after_inserted->prev;
after_inserted->prev = newitem;
--- a/tests/misc_tests.c
+++ b/tests/misc_tests.c
@@ -353,6 +353,19 @@
{
char buffer[10];
cJSON *item = cJSON_CreateString("item");
+ cJSON *array = cJSON_CreateArray();
+ cJSON *item1 = cJSON_CreateString("item1");
+ cJSON *item2 = cJSON_CreateString("corrupted array item3");
+ cJSON *corruptedString = cJSON_CreateString("corrupted");
+ struct cJSON *originalPrev;
+
+ add_item_to_array(array, item1);
+ add_item_to_array(array, item2);
+
+ originalPrev = item2->prev;
+ item2->prev = NULL;
+ free(corruptedString->valuestring);
+ corruptedString->valuestring = NULL;
cJSON_InitHooks(NULL);
TEST_ASSERT_NULL(cJSON_Parse(NULL));
@@ -412,6 +425,8 @@
cJSON_DeleteItemFromObject(item, NULL);
cJSON_DeleteItemFromObjectCaseSensitive(NULL, "item");
cJSON_DeleteItemFromObjectCaseSensitive(item, NULL);
+ TEST_ASSERT_FALSE(cJSON_InsertItemInArray(array, 0, NULL));
+ TEST_ASSERT_FALSE(cJSON_InsertItemInArray(array, 1, item));
TEST_ASSERT_FALSE(cJSON_InsertItemInArray(NULL, 0, item));
TEST_ASSERT_FALSE(cJSON_InsertItemInArray(item, 0, NULL));
TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(NULL, item, item));
@@ -428,10 +443,16 @@
TEST_ASSERT_NULL(cJSON_Duplicate(NULL, true));
TEST_ASSERT_FALSE(cJSON_Compare(item, NULL, false));
TEST_ASSERT_FALSE(cJSON_Compare(NULL, item, false));
+ TEST_ASSERT_NULL(cJSON_SetValuestring(NULL, "test"));
+ TEST_ASSERT_NULL(cJSON_SetValuestring(corruptedString, "test"));
cJSON_Minify(NULL);
/* skipped because it is only used via a macro that checks for NULL */
/* cJSON_SetNumberHelper(NULL, 0); */
+ /* restore corrupted item2 to delete it */
+ item2->prev = originalPrev;
+ cJSON_Delete(corruptedString);
+ cJSON_Delete(array);
cJSON_Delete(item);
}
|