Skip to content

fix insufficient check in cJSON_DetachItemViaPointer#722

Open
hopper-vul wants to merge 1 commit into
DaveGamble:masterfrom
hopper-vul:add-cJSON_DetachItemViaPoianter-null-check
Open

fix insufficient check in cJSON_DetachItemViaPointer#722
hopper-vul wants to merge 1 commit into
DaveGamble:masterfrom
hopper-vul:add-cJSON_DetachItemViaPoianter-null-check

Conversation

@hopper-vul

Copy link
Copy Markdown
Contributor

cJSON_DetachItemViaPointer() will crash if the detached item has field prev is null. The common suitation scenario is the detached item is created by cJSON_Create* APIs and directly pass it to cJSON_DetachItemViaPointer(object, item) call without adding item to object previously. Then the cJSON_DetachItemViaPointer() will crash because it does not check whether the passed item has valid prev field.

As detach a non-existent item is an undesirable behavior, instead of raising an uneasy core dump, this commit adds the NULL check of item->prev in cJSON_DetachItemViaPointer and return NULL to inform user such unexpect behavior (as user will routinely free/handle the detached resources later).

Signed-off-by: hopper-vul [email protected]

cJSON_DetachItemViaPointer() will crash if the detached item has field `prev` is null.
The common suitation scenario is the detached item is created by cJSON_Create* APIs
and directly pass it to cJSON_DetachItemViaPointer(object, item) call without adding
item to object previously. Then the cJSON_DetachItemViaPointer() will crash because
it does not check whether the passed item has valid `prev` field.

As detach a non-existent item is an undesirable behavior, instead of raising an uneasy core dump,
this commit adds the NULL check of `item->prev` in cJSON_DetachItemViaPointer
and return NULL to inform user such unexpect behavior (as user will routinely free/handle the
detached resources later).

Signed-off-by: hopper-vul <[email protected]>
@hopper-vul

Copy link
Copy Markdown
Contributor Author

The smallest case is

#include "cJSON.h"
  
int main(){
        cJSON *object = cJSON_CreateObject();
        cJSON *item = cJSON_CreateObject();
        cJSON *deatch = cJSON_DetachItemViaPointer(object, item); //core dump!
        if (deatch == NULL)
                cJSON_Delete(item);
        cJSON_Delete(object);
        return 0;
}

@hopper-vul

Copy link
Copy Markdown
Contributor Author

@Alanscut @FSMaxB Hi, could you please review this PR? I'm looking forward to your feedback.

Thanks.

@Alanscut

Alanscut commented Jul 1, 2023

Copy link
Copy Markdown
Collaborator

I think the null check of item-prev should be at the place it's visited.

Just think about this scenario:
When item == parent->child, it means item is the first child of parent. In this case, the item->prev is NULL cause it's the first item. In your implementation this will return NULL and it's not what we are expected.

Comment thread cJSON.c
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
{
if ((parent == NULL) || (item == NULL))
if ((parent == NULL) || (item == NULL) || (item->prev == NULL))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer adding this null check to the place where item->prev is used instead of here.
I mean:

    if (item != parent->child)
    {
        if (item->prev == NULL)
        {
            return NULL;
        }
        /* not the first element */
        item->prev->next = item->next;
    }

@MSQFIGHTING

Copy link
Copy Markdown

I think the null check of item-prev should be at the place it's visited.

Just think about this scenario: When item == parent->child, it means item is the first child of parent. In this case, the item->prev is NULL cause it's the first item. In your implementation this will return NULL and it's not what we are expected.
Hi, when i see the readme , i found that if "item == parent->child", the item->prev will be the last object of his parent object and the item->prev->next will be NULL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants