Skip to content

Fix: heap-use-after-free in merge_patch when target is not an object and contains patch (Variant of what #1060 fixed) - #1109

Open
Oculytic wants to merge 1 commit into
DaveGamble:masterfrom
Oculytic:master
Open

Oculytic wants to merge 1 commit into
DaveGamble:masterfrom
Oculytic:master

Conversation

@Oculytic

@Oculytic Oculytic commented Oct 19, 2026 •

Copy link
Copy Markdown

When cJSONUtils_MergePatch(target, patch) is called with an object patch that is a subtree of a non-object target (for example, target is the array [{"a":1}] and patch is its element), merge_patch() called cJSON_Delete(target), which also freed patch, and then read patch->child, triggering a heap-use-after-free.

This is the same situation as #1060, fixed in 6d9f244 for non-object patches; that fix did not cover the branch where the patch is an object and the target is not.

Fix: in that branch, duplicate the patch and create the new object before deleting target, then merge from the copy into the new object and free the copy. On allocation failure, free both and return NULL without touching target.

Reproducer:

    cJSON *patch = target->child;
    cJSON *out = cJSONUtils_MergePatch(target, patch);```

…and contains patch

When cJSONUtils_MergePatch(target, patch) is called with an object
patch that is a subtree of a non-object target (for example, target
is the array [{"a":1}] and patch is its element), merge_patch() called
cJSON_Delete(target), which also freed patch, and then read
patch->child, triggering a heap-use-after-free.

This is the same situation as DaveGamble#1060, fixed in 6d9f244 for non-object
patches; that fix did not cover the branch where the patch is an
object and the target is not.

Fix: in that branch, duplicate the patch and create the new object
before deleting target, then merge from the copy into the new object
and free the copy. On allocation failure, free both and return NULL
without touching target.

Reproducer:
    cJSON *target = cJSON_Parse("[{\"a\":1}]");
    cJSON *patch = target->child;
    cJSON *out = cJSONUtils_MergePatch(target, patch);
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.

1 participant