@@ -827,75 +827,36 @@ second is small and unbreaks the platform immediately.
827827Found while reproducing #369 , and NOT that issue's cause: the reporter is on
828828Windows CPU/Vulkan and sees wrong-language output, not silence.
829829
830- ## CLAIMED 2026-09-07 — stb_vorbis heap overflow (security), root cause found
831-
832- Worktree: main (` /mnt/volume1/CrispASR ` ). Taking the OPEN item below.
833-
834- ROOT CAUSE, confirmed by arithmetic against the ASAN report, not inferred:
835-
836- f->comment_list_length = get32_packet(f); // attacker uint32
837- f->comment_list = setup_malloc(f, sizeof(char*) * f->comment_list_length);
838- memset(f->comment_list, 0, sizeof(char*) * f->comment_list_length);
839-
840- ` setup_malloc(vorb *f, int sz) ` takes an ** int** . With length = 1646854400,
841- ` 8 * length ` = 13,174,835,200 truncates to ** 289,933,312** — exactly the
842- allocation size ASAN reported. The ` memset ` computes the same product but
843- ` sizeof ` makes it ` size_t ` , so it is ** 13,174,835,200** — exactly the write size
844- ASAN reported. THE ALLOCATION TRUNCATES AND THE CONSUMER DOES NOT. Same shape as
845- the ` resample_polyphase ` n_out overflow fixed 2026-09-04 (int guard over a value
846- that had already wrapped).
847-
848- UPSTREAM HAS NOT FIXED IT (checked, per the next-steps note below):
849- nothings/stb master still has ` setup_malloc(vorb *f, int sz) ` and the same
850- truncating multiply. So there is nothing to pull, the vendored patch is correct,
851- and upstream is vulnerable by the same truncation — it lacks our ` memset ` , so
852- instead of one 13 GB write its ` for ` loop walks ` comment_list[i] ` past the short
853- allocation. Worth reporting upstream once ours is fixed.
854-
855- NOTE the memset is itself a CrispASR patch, added to fix an earlier fuzz crash
856- (NULL comment_list freed by vorbis_deinit). It did not create the truncation, but
857- it converted a gradual overflow into an immediate 13 GB one.
858-
859- Plan: bound ` comment_list_length ` before allocating so the product cannot
860- truncate, size the allocation in ` size_t ` , craft a minimal Ogg reproducer into
861- ` tests/fuzz/regressions/ ` (which now actually replays — the copy step counts its
862- seeds since 2026-09-04), and let ` linux-fuzz-smoke ` be the gate.
863-
864- ## OPEN 2026-08-18 — stb_vorbis heap overflow on untrusted audio (security)
865-
866- Found incidentally by ` linux-fuzz-smoke ` on PR #371 , which does not touch that
867- code — fuzzing is stochastic and it happened to surface there. NOT that PR's
868- fault, and it reproduces from the audio fuzzer, not from anything in the diff.
869-
870- ==6684==ERROR: AddressSanitizer: heap-buffer-overflow
871- WRITE of size 13174835200 at 0x7f29bad7d000
872- #0 memset
873- #1 start_decoder(stb_vorbis*) examples/stb_vorbis.c:3683
874- #2 stb_vorbis_open_memory examples/stb_vorbis.c:5141
875- #3 stb_vorbis_decode_memory examples/stb_vorbis.c:5419
876- #4 crispasr_webm_decode(...) src/crispasr_audio.cpp:1405
877- #5 crispasr_audio_load src/crispasr_audio.cpp:2801
878- #6 LLVMFuzzerTestOneInput tests/fuzz/fuzz_audio_load.cpp:40
879-
880- 0x7f29bad7d000 is located 0 bytes after a 289933312-byte region
881- allocated by setup_malloc(stb_vorbis*, int) examples/stb_vorbis.c:960
882-
883- A 13 GB ` memset ` past a 289 MB allocation: the size computation in
884- ` start_decoder ` overflows or is not validated against the allocation
885- ` setup_malloc ` actually made. Reachable through ` crispasr_audio_load ` , i.e. on
886- ANY caller-supplied audio file — the CLI, the HTTP server's upload path, and
887- every binding. That makes it a memory-safety issue on untrusted input, not just
888- a fuzz curiosity.
889-
890- Severity note, honestly: a 13 GB write will fault almost immediately in
891- practice, so the realistic outcome is a crash (DoS) rather than exploitable
892- corruption. Worth fixing regardless, and worth checking whether a smaller,
893- more controllable overflow is reachable from the same path.
894-
895- Next steps: reproduce locally with a fuzz build
896- (` -DCRISPASR_FUZZ=ON -DCRISPASR_SANITIZE_ADDRESS=ON ` ), minimise the input, then
897- decide between bounds-checking ` start_decoder ` and pulling a newer stb_vorbis.
898- Check whether upstream stb has already fixed it before patching a vendored copy.
830+ ## DONE 2026-09-07 — stb_vorbis heap overflow on untrusted audio (security)
831+
832+ OPEN since 2026-08-18; fixed in ` 2d2c13ee ` . Reachable from ` crispasr_audio_load `
833+ — CLI, server upload, every binding.
834+
835+ ` setup_malloc ` takes an ** int** , so ` sizeof(char*) * comment_list_length `
836+ truncated 13,174,835,200 to 289,933,312 and allocated that, while the ` memset `
837+ on the next line computed the same product in ` size_t ` and wrote the full 13 GB.
838+ Both numbers match the original ASAN report exactly. One quantity, computed two
839+ ways, disagreeing across a boundary — the same shape as the
840+ ` resample_polyphase ` ` n_out ` overflow fixed 2026-09-04.
841+
842+ Upstream nothings/stb has NOT fixed it (checked, as the item asked): master
843+ still carries the int-typed ` setup_malloc ` and the same multiply, so there was
844+ nothing to pull, and upstream is vulnerable by the same truncation. Worth
845+ reporting there — not yet done.
846+
847+ Fixed at the call site (bound the count before the multiply: no truncation, and
848+ at most ` stream_len/4 ` comments since each costs 4 bytes for its own length
849+ field) and at the choke point (` setup_malloc ` rejects a negative ` sz ` ). The
850+ vendor and per-comment strings on the same path got the same data-derived bound.
851+
852+ ` tests/fuzz/regressions/ogg-comment-count-int-overflow.ogg ` (101 bytes,
853+ generated by ` tools/gen-ogg-comment-fuzz-seed.py ` ) reproduces the original
854+ report exactly against the pre-fix decoder — same write size, same region size,
855+ same four stack frames and line numbers — and is clean after. The corpus
856+ README's previously-missing seed value (` 0x3FFFFFFF ` ) was generated and tested
857+ and reproduces nothing today, so that row is retired rather than restored.
858+
859+ REMAINING, small: report the truncation upstream to nothings/stb.
899860
900861## Start here
901862
0 commit comments