Stack-overflow via deep JSON array nesting under ASan+-O0, below CJSON_NESTING_LIMIT
Maintainer thường phản hồi trong vòng 12 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 68/100
- Loại issue
- Tài liệu
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- c
- Lĩnh vực
- documentation
Hướng nghiên cứu
Bắt đầu trong cJSON.c bằng cách tìm CJSON_NESTING_LIMIT và tài liệu hoặc chú thích hiện có về nó. Xem xét reproducer sanitizer đã được báo cáo cùng các chi tiết về quá trình build, sau đó ghi lại rằng độ sâu lồng nhau an toàn thực tế phụ thuộc vào cấu hình build, đặc biệt là với -O0 và ASan; công việc hoàn tất khi tài liệu về giới hạn nêu rõ kỳ vọng này cho người dùng fuzzing và sanitizer.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
Under an ASan + -O0 build (the standard configuration for fuzzing/CI sanitizer runs), a deeply nested JSON array triggers a native stack overflow before CJSON_NESTING_LIMIT (1000) is ever reached, because the limit bounds the number of recursive parser calls but not the size of each call's stack frame, and ASan instrumentation plus disabled optimization inflate that frame size substantially.
This is not an exploitable issue in a normal optimized release build (verified below) — filing this as a robustness/documentation note, not a security report.
Repro
Minimized input: a JSON value consisting of 755 consecutive [ bytes, no closing brackets, no other content.
$ ./cjson_asan_o0 < deepnest_755.json
==PID==ERROR: AddressSanitizer: stack-overflow on address 0x...
<empty stack>
SUMMARY: AddressSanitizer: stack-overflow
(No symbolized backtrace — ASan's own crash-reporting code cannot run once the stack is this exhausted, which is typical for pure stack-overflow crashes as opposed to heap-buffer-overflow.)
Build used to reproduce: cJSON.c compiled with -O0 -fsanitize=address -g, default thread/process stack size (8 MiB on the Linux machine used here). Binary search found the exact boundary on that machine: 754 levels of [ is parsed/rejected cleanly (cJSON_ParseWithLength returns NULL), 755 crashes.
Why the existing limit does not catch it here
CJSON_NESTING_LIMIT counts recursive calls, not stack bytes consumed. Under -O0, every local gets its own stack slot (no register allocation), and ASan adds redzone padding around each stack allocation. The combined per-call frame size under this build is large enough that the process stack is exhausted well before the 1000-call counter would reject the input.
Confirms it is release-build-safe
The same inputs (780, 1000, 1500, 5000, 50000 levels of [) were tested against an identical harness built -O2, no sanitizers: all are rejected cleanly, exit code 0, no crash, in every case. The nesting limit does its job as documented in a normal build; the gap only appears under sanitizer instrumentation.
Suggested fix
Options, roughly in order of effort:
- Note in the
CJSON_NESTING_LIMITdocumentation that the effective safe depth is build-configuration-dependent (much lower under-O0/ASan/MSan than in an optimized release build), so people fuzzing or testing cJSON with sanitizers know a stack-overflow at a shallower depth than 1000 is expected, not a new bug. - Optionally lower the default limit, or make it configurable relative to a measured/available stack size, if protecting sanitizer/debug builds against this specific crash is a goal.
Happy to share the exact harness and inputs if useful. Reported by an independent fuzzing exercise, no CVE requested given the release-build behavior is correct.
- Ngôn ngữ chính
- C
- Star
- 13.1k
- Fork
- 3.6k
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của DaveGamble/cJSON
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
DaveGamble/cJSON#1106 ·
Maintainer thường phản hồi trong vòng 12 ngày
-
Undefined-Behavior in function cJSON_SetNumberHelperCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
DaveGamble/cJSON#1100 · 1 reaction ·
Maintainer thường phản hồi trong vòng 12 ngày
-
CMake config files contain absolute install pathsCó thể đã có người làm @akashdeshmukh-git đã nhận 6 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
DaveGamble/cJSON#1094 · 9 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 12 ngày
-
Use-after-free in cJSONUtils_ApplyPatches when a patch removes the patch arrayCó thể đã có người làm @iliasabk đã nhận 40 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
DaveGamble/cJSON#1082 ·
Maintainer thường phản hồi trong vòng 12 ngày
-
Use-after-free in cJSON_ReplaceItemInObject when the key is the item's own nameCó thể đã có người làm @iliasabk đã nhận 41 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
DaveGamble/cJSON#1081 ·
Maintainer thường phản hồi trong vòng 12 ngày
Tất cả issue của DaveGamble/cJSON
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
InukaAsith/TwinDesk#84 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
CanadaHonk/porffor#426 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
FujiNetWIFI/fujinet-firmware#2221 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 77/100
raysan5/raylib.com#132 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100