mirror of
https://github.com/DaveGamble/cJSON.git
synced 2026-10-13 10:15:04 +00:00
Fix: heap-use-after-free in merge_patch when patch is subtree of target (#1065)
When cJSONUtils_MergePatch(target, patch) is called with a non-object patch (scalar, array, or NULL) that happens to be a subtree of target, merge_patch() called cJSON_Delete(target) first, which freed the patch memory, and then cJSON_Duplicate(patch, 1) read the already-freed memory, triggering a heap-use-after-free (detected by AddressSanitizer at cJSON_Duplicate_rec, cJSON.c:2808). Fix: duplicate the patch first into a local variable, then delete the target, then return the duplicate. This matches the Option B approach proposed in issue #1060. Verified locally: - Reproduced the UAF with a minimal PoC under ASan before the fix. - After the fix the PoC runs cleanly (exit 0, correct result [1,2,3]). - Added a regression unit test (merge_patch_should_not_read_freed_memory_when_patch_is_subtree). - Full ctest suite passes (22/22 tests). Fixes #1060 Signed-off-by: lilu <lilu@kylinos.cn>
This commit is contained in:
+6
-2
@@ -1324,9 +1324,13 @@ static cJSON *merge_patch(cJSON *target, const cJSON * const patch, const cJSON_
|
||||
|
||||
if (!cJSON_IsObject(patch))
|
||||
{
|
||||
/* scalar value, array or NULL, just duplicate */
|
||||
/* scalar value, array or NULL, just duplicate.
|
||||
* Duplicate the patch first in case it is a subtree of target,
|
||||
* otherwise cJSON_Delete(target) would free the patch memory
|
||||
* and the subsequent cJSON_Duplicate would read freed memory. */
|
||||
cJSON *duplicate = cJSON_Duplicate(patch, 1);
|
||||
cJSON_Delete(target);
|
||||
return cJSON_Duplicate(patch, 1);
|
||||
return duplicate;
|
||||
}
|
||||
|
||||
if (!cJSON_IsObject(target))
|
||||
|
||||
Reference in New Issue
Block a user