Repository navigation
fix(core): end the argv array with NULL - #70
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
📒 Files selected for processing (2)
✨ Finishing Touches📝 Generate docstrings
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
The PR fixes a missing NULL terminator in the argv array passed to ffmpeg. The stringsToPtr function now allocates one extra slot and writes NULL into it, preventing fftools from reading past the array when the last argument is an option like -h. Two tests are added: one that poisons the heap to catch a missing terminator, and one that verifies repeated timeout/exec cycles work.
review-bot, model nvidia/nemotron-3-ultra-550b-a55b:free, verdict approve
What
exec()andffprobe()passed ffmpeg an argv array with no NULL after the last argument. fftools readsargv[argc]when the last argument is an option, so a trailing-h,-versionor-formatsread whatever the heap held past the allocation. Most of the time that is a harmless pointer. Sometimes it is not, and the core throwsRuntimeError: memory access out of bounds.The fix allocates one more slot and writes NULL into it.
Root cause
The failing master run (37342775756,
[ffmpeg-core][mt] setLogger() should handle logs) has this wasm stack, outermost last:strlenstrdupshow_help, which callsav_strdup(arg ? arg : "")write_option, which calls the option'sfunc_argffmpeg()and the exported_ffmpegI identified them by disassembling the run's own core artifact.
parse_optionscallsparse_option(optctx, opt, argv[optindex], ...), so for-has the last argumentargisargv[argc].stringsToPtr()allocated exactlyargcslots, so that is the word after a 16-byte allocation, and it is whatever the previous heap user left.Reproduced on the unfixed core from that run:
argv[argc]to NULL by hand runs-hfine. Setting it to0x7ffffff0throws the same error with the same six frames.0. After anyexec(), timed out or not, it is a non-zero heap value (e45db4,93aa7e8, ...). A pointer into valid memory only makesstrdupread garbage. A value that is out of range, or that has no NUL before the end of memory, traps.So the timeout was not the cause. It changed the heap contents, which made the crash show up there. The #63 case (
lavfiwith a 50 ms timeout, thenexec -h) is the same bug. The single-thread core has the same defect, since both sharebind.js. A poisoned allocation traps it too.The timeout path itself is sound.
sch_stop()joins every scheduler thread beforeexec()returns, and five timeout and exec rounds in a row pass on both cores with the fix. No core restart or wrapper change is needed.Tests
exec() argvfills every_mallocmade byexec()with a bad pointer, then runsexec("-h"). It fails on the unfixed core (mt and st, locally against the CI artifacts of master) and passes now.exec() after a timeoutruns timeout,-hand a transcode five times in a row.Noticed, not fixed
None.