This is an automated email from the git hooks/post-receive script.
Git pushed a commit to branch master
in repository ffmpeg.
The following commit(s) were added to refs/heads/master by this push:
new c79dfd29e6 avcodec/h264_slice: guard color_frame() against
chroma-width underflow
c79dfd29e6 is described below
commit c79dfd29e6afca56294395be843d98d10858a7fa
Author: Franciszek Kalinowski <[email protected]>
AuthorDate: Tue May 19 09:36:50 2026 +0200
Commit: michaelni <[email protected]>
CommitDate: Mon May 25 13:16:03 2026 +0000
avcodec/h264_slice: guard color_frame() against chroma-width underflow
In the >= 9 bit path, color_frame() does
`av_memcpy_backptr(dst + 2, 2, bytes - 2)`. When the effective chroma width
is 1 pixel (bytes == 1) the count becomes -1 and the underlying fill16()
loop runs roughly 2^32 times, producing a heap overflow. The original count
was also wrong in units (pixels rather than bytes); fix that at the same
time so the 2-pixel case still fills both pixels.
Confirmed via a standalone harness reproducing av_memcpy_backptr's fill16
loop with cnt = -1; reaching the call from a crafted H.264 bitstream
requires Hi10P plus a frame_num gap on a frame whose effective chroma width
is 1 pixel, which is hard to express but is reachable via mid-stream SPS
changes. Compiles cleanly; no regressions seen running existing crafted
H.264 PoCs and trivial transcodes.
Reported by Franciszek Kalinowski (isec.pl / striga.ai) and Bartosz
Smigielski.
---
libavcodec/h264_slice.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index dbf7f60230..e3b4436fcb 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -316,8 +316,10 @@ static void color_frame(AVFrame *frame, const int c[4])
int bytes = is_chroma ? AV_CEIL_RSHIFT(frame->width,
desc->log2_chroma_w) : frame->width;
int height = is_chroma ? AV_CEIL_RSHIFT(frame->height,
desc->log2_chroma_h) : frame->height;
if (desc->comp[0].depth >= 9) {
- ((uint16_t*)dst)[0] = c[p];
- av_memcpy_backptr(dst + 2, 2, bytes - 2);
+ if (bytes >= 1)
+ ((uint16_t*)dst)[0] = c[p];
+ if (bytes >= 2)
+ av_memcpy_backptr(dst + 2, 2, 2 * (bytes - 1));
dst += frame->linesize[p];
for (int y = 1; y < height; y++) {
memcpy(dst, frame->data[p], 2*bytes);
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]