DaveGamble / cJSON

Ultralightweight JSON parser in ANSI C
MIT License
10.83k stars 3.22k forks source link

bug for cJSON_InsertItemInArray function #802

Closed Du4t closed 11 months ago

Du4t commented 11 months ago

Description

If the the newitem passed in cJSON_InsertItemInArray dont have prev, the newitem->prevwill be null. The null pointer dereference will cause SEGV in function cJSON_InsertItemInArray cJSON.c:2287

Version

commit cb8693b058ba302f4829ec6d03f609ac6f848546 (HEAD -> master, tag: v1.7.16, origin/master, origin/HEAD)
Author: Alan Wang <wp_scut@163.com>
Date:   Wed Jul 5 11:22:19 2023 +0800

Related Code

CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
{
    cJSON *after_inserted = NULL;

    if (which < 0)
    {
        return false;
    }

    after_inserted = get_array_item(array, (size_t)which);
    if (after_inserted == NULL)
    {
        return add_item_to_array(array, newitem);
    }

    newitem->next = after_inserted;
    newitem->prev = after_inserted->prev;
    after_inserted->prev = newitem;
    if (after_inserted == array->child)
    {
        array->child = newitem;
    }
    else
    {
        newitem->prev->next = newitem; // <== here
    }
    return true;
}

Impact

Potentially causing DoS

carnil commented 11 months ago

This appears to have CVE-2023-50471 assigned.

PeterAlfredLee commented 11 months ago

Hi @Du4t It will be appreciated if you can provide a POC.

Currently I tested with newitem->prev as NULL but I can not reproduce this problem.

Besides this, I don't think it's a good practice to request a CVE without this problem being confirmed.

PeterAlfredLee commented 11 months ago

The only way I can reproduce this problem is to pass a corrupted array to cJSON_InsertItemInArray like this:

    cJSON *item = cJSON_CreateString("item");
    cJSON *array = cJSON_CreateArray();
    cJSON *temp1 = cJSON_CreateString("item1");
    cJSON *temp2 = cJSON_CreateString("item2");

    add_item_to_array(array, temp1);
    add_item_to_array(array, temp2);

    // manually set the prev to be NULL to make a corrupted array
    temp2->prev = NULL;

    // SEGV as after_inserted->prev is NULL, which is passed to newitem->prev, making newitem->prev->next a NULL pointer using
    cJSON_InsertItemInArray(array, 1, item);

Is this the correct way to reproduce this problem?

ArchanaWind commented 11 months ago

Hi,

Is there any plan to backport the fix to 1.7.16 version.