any thoughts on this?
 - Ian Klatzco

On Tue, May 19, 2026 at 10:09 AM Ian Klatzco <[email protected]> wrote:
>
> adx_parse() relies on one of two paths setting `next` before calling
> ff_combine_frame(): either the in-band ADX header is found by the
> state-machine scan, or avctx->ch_layout.nb_channels has been set by
> the caller (i.e. the demuxer). When neither condition holds on the
> first invocation -- as happens when a USM container declares
> audio_codec=2 (ADX) but omits the num_channels key in its @UTF
> metadata -- next stays at END_NOT_FOUND (-1), pc->buffer is still
> NULL, and the av_assert0(next >= 0 || pc->buffer) at
> libavcodec/parser.c:258 fires, aborting the process.
>
> This is reachable from libavformat consumers (ffmpeg, ffprobe,
> applications using libav*) via a crafted USM file; trigger conditions:
>
>   1. audio_codec=2 set (ADX parser registered)
>   2. num_channels absent or zero
>   3. audio payload contains no ADX magic anywhere
>   4. first call to adx_parse for this stream
>
> The fix is parser-side: if neither the in-band header has been found
> nor channel info is available, consume the input without emitting a
> frame rather than handing END_NOT_FOUND with an empty buffer to
> ff_combine_frame.
>
> Found by fuzzing target_dem_usm_fuzzer with a corpus that combined
> synthetic seeds and real USM samples; the variant the fuzzer found is
> a mutation of a real sample's @UTF block that removes num_channels
> while leaving audio_codec=2 intact.
>
> Signed-off-by: Ian Klatzco <[email protected]>
> ---
>  libavcodec/adx_parser.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/libavcodec/adx_parser.c b/libavcodec/adx_parser.c
> index c897ba223a..32a99c8ec6 100644
> --- a/libavcodec/adx_parser.c
> +++ b/libavcodec/adx_parser.c
> @@ -85,6 +85,12 @@ static int adx_parse(AVCodecParserContext *s1,
>              s->remaining -= buf_size;
>      }
>
> +    if (!s->header_size && avctx->ch_layout.nb_channels <= 0) {
> +        *poutbuf      = NULL;
> +        *poutbuf_size = 0;
> +        return buf_size;
> +    }
> +
>      if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) {
>          *poutbuf      = NULL;
>          *poutbuf_size = 0;
> --
> 2.47.3
>
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to