-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Description
Description of the bug
This vulnerability represents part of a systematic design flaw in the cJSON library regarding circular reference handling. The library exhibits inconsistent behavior across its APIs when dealing with circular references, creating a fundamental architectural problem. The specific manifestation here is a stack overflow when printing JSON structures containing circular array references. The cJSON_CreateArrayReference function allows creation of array references that form cycles, but the print functions lack cycle detection for arrays, leading to infinite recursion and stack overflow.
To Reproduce
Here's a minimal example that reproduces the array circular reference stack overflow:
#include "cJSON.h"
#include <stdlib.h>
#include <stdio.h>
int main() {
// Create root object
cJSON *root = cJSON_CreateObject();
// Create integer array
int numbers[] = {1, 2, 3, 4, 5};
cJSON *int_array = cJSON_CreateIntArray(numbers, 5);
if (int_array) {
// Add array to root object
cJSON_AddItemToObject(root, "int_array", int_array);
// Create reference to the same array - this creates a cycle
cJSON *array_ref = cJSON_CreateArrayReference(int_array);
if (array_ref) {
cJSON_AddItemToObject(root, "array_ref", array_ref);
}
// Add other items
cJSON_AddTrueToObject(root, "true_value");
cJSON_AddFalseToObject(root, "false_value");
}
printf("Attempting to print structure with circular array reference...\n");
// This will cause infinite recursion due to the circular array reference
char *printed = cJSON_PrintUnformatted(root);
if (printed) {
free(printed);
}
cJSON_Delete(root);
return 0;
}Steps to reproduce:
- Compile the above code with cJSON library and AddressSanitizer
- Run the program
- Observe the stack overflow crash due to infinite recursion in array printing
Version Information
- cJSON version: Current master branch
- OS and version: Linux (tested in Docker container with AddressSanitizer)
- Compiler: Clang with -fsanitize=address
Stack Trace
ERROR: AddressSanitizer: stack-overflow on address 0x7ffd3988efb8
#3 0x563875d6b131 in print_number /src/cjson/cJSON.c:613:18
#4 0x563875d6b131 in print_value /src/cjson/cJSON.c:1457:20
#5 0x563875d6b27b in print_array /src/cjson/cJSON.c:1615:14
#6 0x563875d6b27b in print_value /src/cjson/cJSON.c:1481:20
#7 0x563875d6b27b in print_array /src/cjson/cJSON.c:1615:14
#8 0x563875d6b27b in print_value /src/cjson/cJSON.c:1481:20
#9 0x563875d6b27b in print_array /src/cjson/cJSON.c:1615:14
#10 0x563875d6b27b in print_value /src/cjson/cJSON.c:1481:20
... [pattern repeats 400+ times]
#488 0x563875d6b27b in print_array /src/cjson/cJSON.c:1615:14
#489 0x563875d6b27b in print_value /src/cjson/cJSON.c:1481:20
SUMMARY: AddressSanitizer: stack-overflow /src/cjson/cJSON.c:613:18 in print_number
Discussion
In #880 and #882 , I observed similar issues. Although these pertain to different APIs, the underlying problem with circular references is analogous.
You mentioned that “cJSON is designed to believe the input arguments are correct” and “we are aware of circular references,” which implies that cJSON acknowledges the issue but considers it the responsibility of the user to prevent it.
However, I noticed that #888
partially addresses circular dependency issues for some other APIs, yet no circular dependency detection has been added to many of the remaining APIs.
In summary, my observation is as follows:
If circular dependency issues are considered the user’s responsibility, then this PR appears largely meaningless. Conversely, if cJSON should guarantee safety against circular dependencies, then applying the approach of this PR would require implementing similar protections across all APIs—an endeavor with significant cost. Moreover, in my view, the modifications in this PR alone do not resolve the underlying architectural problem.
I would like to know whether you agree with this perspective, and whether you see a feasible solution. I understand that a comprehensive solution may involve considerable effort, but I am still eager to discuss this with you.