mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-16 04:32:47 +02:00
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.
This commit is contained in:
committed by
michaelni
parent
34dfa8bf2b
commit
c79dfd29e6
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user