PR #22887 opened by padenot
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22887
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22887.patch
`ff_parse_a53_cc()` uses `get_bits()` which performs AV_RB32 loads and
requires `AV_INPUT_BUFFER_PADDING_SIZE` trailing bytes past the logical
end of its input. `dav1d`'s ITU-T T.35 payload buffers carry no such
padding, so passing `gb.buffer` directly caused a heap-buffer-overflow
read of up to 3 bytes past the end of the allocation.
Copy the remaining bytes into a freshly-allocated, zero-padded buffer
before calling `ff_parse_a53_cc()`.
A python script that can generate an av1 frame that triggers this is attached,
alongside its output (for convenience).
Using an ASAN-enabled `ffmpeg` built from a recent revision, `ffmpeg -f obu
-i repro.obu -f null -` will crash with the following stack:
```
==38960==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x50200000201a at pc 0x56c245667070 bp 0x784b82476130 sp
0x784b82476120
READ of size 4 at 0x50200000201a thread T67 (dec0:0:libdav1d)
#0 0x56c24566706f in get_bits libavcodec/get_bits.h:342
#1 0x56c245667b82 in ff_parse_a53_cc libavcodec/atsc_a53.c:115
#2 0x56c24564551f in parse_itut_t35_metadata libavcodec/libdav1d.c:387
#3 0x56c245647e43 in libdav1d_receive_frame libavcodec/libdav1d.c:622
#4 0x56c245619204 in ff_decode_receive_frame_internal
libavcodec/decode.c:629
#5 0x56c24561950e in decode_receive_frame_internal libavcodec/decode.c:662
#6 0x56c24561a595 in ff_decode_receive_frame libavcodec/decode.c:816
#7 0x56c2455b2dde in avcodec_receive_frame_flags libavcodec/avcodec.c:719
#8 0x56c2453d0a9c in packet_decode fftools/ffmpeg_dec.c:754
#9 0x56c2453d2552 in decoder_thread fftools/ffmpeg_dec.c:955
#10 0x56c24545f318 in task_wrapper fftools/ffmpeg_sched.c:2694
0x50200000201d is located 0 bytes after 13-byte region
[0x502000002010,0x50200000201d)
allocated by thread T67 (dec0:0:libdav1d) here:
#0 0x784bb96fd9c7 in malloc
../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
#1 0x784bb93fde8c in dav1d_parse_obus ../src/obu.c:1488
```
This has been found by internal fuzzing in Firefox but is unlikely to be an
exploitable problem in practice, since it's just a small OOB read past a
heap-allocated buffer. Maybe if we're really unlucky it can crash.
>From 12df5c04354b2205f266fcab8cc31c7eecceaab5 Mon Sep 17 00:00:00 2001
From: Paul Adenot <[email protected]>
Date: Wed, 22 Apr 2026 11:27:16 +0000
Subject: [PATCH] avcodec/libdav1d: copy A/53 CC payload into a padded buffer
ff_parse_a53_cc() uses get_bits() which performs AV_RB32 loads and
requires AV_INPUT_BUFFER_PADDING_SIZE trailing bytes past the logical
end of its input. dav1d's ITU-T T.35 payload buffers carry no such
padding, so passing gb.buffer directly caused a heap-buffer-overflow
read of up to 3 bytes past the end of the allocation.
Copy the remaining bytes into a freshly-allocated, zero-padded buffer
before calling ff_parse_a53_cc().
---
libavcodec/libdav1d.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index 2eaeefc71a..2a81392c34 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -23,6 +23,7 @@
#include "libavutil/avassert.h"
#include "libavutil/cpu.h"
+#include "libavutil/mem.h"
#include "libavutil/film_grain_params.h"
#include "libavutil/hdr_dynamic_metadata.h"
#include "libavutil/mastering_display_metadata.h"
@@ -383,8 +384,14 @@ static int parse_itut_t35_metadata(Libdav1dContext *dav1d,
Dav1dPicture *p,
switch (user_identifier) {
case MKBETAG('G', 'A', '9', '4'): { // closed captions
AVBufferRef *buf = NULL;
+ int cc_size = bytestream2_get_bytes_left(&gb);
+ uint8_t *padded = av_mallocz(cc_size +
AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!padded)
+ return AVERROR(ENOMEM);
+ memcpy(padded, gb.buffer, cc_size);
- res = ff_parse_a53_cc(&buf, gb.buffer,
bytestream2_get_bytes_left(&gb));
+ res = ff_parse_a53_cc(&buf, padded, cc_size);
+ av_freep(&padded);
if (res < 0)
return res;
if (!res)
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]