Repository navigation
Conversation
…check (CCExtractor#2443) Fixes CCExtractor#2443 Fixes CCExtractor#2449 In `process_avc_sample()`, the bounds check `i + nal_length <= previous_index || i + nal_length > s->dataLength` was evaluated in 32-bit unsigned arithmetic. A crafted `nal_length` near `UINT32_MAX` wraps around into `(previous_index, s->dataLength]`, bypassing both checks and causing a heap-buffer-overflow at `s->data[i]` (line 99) and inside `do_NAL()` (line 100). Perform the addition in 64-bit unsigned arithmetic (`uint64_t`) so `i + nal_length` cannot wrap around.
|
Hi @cfsmp3, just a quick note here as well: The code fix is fully tested and ready for review (Docker, Mac, and Windows checks are all green). The Linux CI checks are failing early here too because of the same Let me know if any changes are needed in the code! |
cfsmp3
left a comment
There was a problem hiding this comment.
This is Carlos' claude doing the first pass. Before Carlos takes a look, please address these issues.
The AVC fix works. An MP4 whose AVC sample ends in a 4-byte NAL length of 0xFFFFFFFF gives ASan heap-buffer-overflow at mp4.c:99 on master; this branch reports the corrupted sample and stops reading.
The fix is incomplete. The same 32-bit check, and the same overflow, exists in two more places:
process_hevc_sample(),src/lib_ccx/mp4.c:154:if (i + nal_length <= previous_index || i + nal_length > s->dataLength). The same crafted file with an HEVC track still gives ASanheap-buffer-overflowatmp4.c:168on this branch.- The FFmpeg MP4 path,
src/lib_ccx/mp4_rust_bridge.c:66:if (i + nal_length <= prev || i + nal_length > data_length)withunsigned intoperands.
Please apply the same (uint64_t) widening to both (or the equivalent nal_length > data_length - i form), so all three NAL loops share one safe check.
|
@cfsmp3 I have applied the (uint64_t) widening to all three NAL loops as requested. Please take a look! |
CCExtractor CI platform finished running the test files on linux. 172/238 tests matched the approved output:
66 tests do not match the approved output. That is the pass/fail verdict. Whether this branch caused it is a separate question, answered below.
Compared with the tip of master — test 9878, commit 185fe3f:
Compared with the commit this branch was cut from: the same run as the tip of master (test 9878), so the comparison above already covers it. No test changes behaviour relative to the tip of master: every failure above fails there too, byte for byte. The approved output for those tests is out of date, which is a baseline to review rather than a regression in this branch. |
CCExtractor CI platform finished running the test files on windows. 172/238 tests matched the approved output:
66 tests do not match the approved output. That is the pass/fail verdict. Whether this branch caused it is a separate question, answered below.
Compared with the tip of master — test 9693, commit af4b28d:
Fail on both but produce different output — behaviour moved even though the verdict did not:
Fail there, pass here:
Compared with the commit this branch was cut from: the same run as the tip of master (test 9693), so the comparison above already covers it. This branch changes the behaviour of 42 test(s) relative to the tip of master. Those are the ones worth looking at; anything else in the list fails the same way on both sides. |
Fixes #2443
Fixes #2449
In
process_avc_sample(), the bounds checki + nal_length <= previous_index || i + nal_length > s->dataLengthwas evaluated in 32-bit unsigned arithmetic. A craftednal_lengthnearUINT32_MAXwraps around into(previous_index, s->dataLength], bypassing both checks and causing a heap-buffer-overflow read ats->data[i](src/lib_ccx/mp4.c:99) and insidedo_NAL()(src/lib_ccx/mp4.c:100).Perform the bounds-check addition in 64-bit unsigned arithmetic (
uint64_t) soi + nal_lengthcannot wrap around.In raising this pull request, I confirm the following (please check boxes):
Reason for this PR:
Sanity check:
Repro instructions:
ccextractorwith AddressSanitizer (-fsanitize=address).ccextractor crash-input.binusing the malformed MP4 sample attached in [Security] Heap buffer overflow (OOB read past GPAC sample buffer) in process_avc_sample() at mp4.c:99 when parsing a crafted MP4 file #2443 / [Security] Heap buffer overflow (OOB read past GPAC sample buffer) in process_avc_sample() at mp4.c:99 when parsing a crafted MP4 file #2449.process_avc_sample()aborts with a heap-buffer-overflow atsrc/lib_ccx/mp4.c:99. With this fix, the 64-bit bounds check catches the overflowednal_length, logs the corrupted sample message, and exits cleanly.