PR #23725 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23725
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23725.patch

Fixes: signed integer overflow
Fixes: 
519649309/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_TDSC_fuzzer-6322382028734464
Found-by: continuous fuzzing process 
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg



>From ff5b222d5b21b44564cef75a87ddce7906798d72 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Wed, 1 Jul 2026 06:18:07 +0200
Subject: [PATCH] avcodec/tdsc: reject out-of-frame cursor position

Fixes: signed integer overflow
Fixes: 
519649309/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_TDSC_fuzzer-6322382028734464
Found-by: continuous fuzzing process 
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
---
 libavcodec/tdsc.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/libavcodec/tdsc.c b/libavcodec/tdsc.c
index e8d37a4e3f..ca9dd0f0a6 100644
--- a/libavcodec/tdsc.c
+++ b/libavcodec/tdsc.c
@@ -146,8 +146,7 @@ static void tdsc_paint_cursor(AVCodecContext *avctx, 
uint8_t *dst, int stride)
 {
     TDSCContext *ctx = avctx->priv_data;
     const uint8_t *cursor = ctx->cursor;
-    int x = ctx->cursor_x - ctx->cursor_hot_x;
-    int y = ctx->cursor_y - ctx->cursor_hot_y;
+    int x, y;
     int w = ctx->cursor_w;
     int h = ctx->cursor_h;
     int i, j;
@@ -155,6 +154,16 @@ static void tdsc_paint_cursor(AVCodecContext *avctx, 
uint8_t *dst, int stride)
     if (!ctx->cursor)
         return;
 
+    /* A cursor position outside the frame is invalid; skip drawing it.
+     * cursor_x/y come straight from the bitstream, so bound them before
+     * the (16 bit) hot spot shift to avoid overflowing the clip math. */
+    if ((unsigned)ctx->cursor_x >= ctx->width ||
+        (unsigned)ctx->cursor_y >= ctx->height)
+        return;
+
+    x = ctx->cursor_x - ctx->cursor_hot_x;
+    y = ctx->cursor_y - ctx->cursor_hot_y;
+
     if (x + w > ctx->width)
         w = ctx->width - x;
     if (y + h > ctx->height)
@@ -201,12 +210,6 @@ static int tdsc_load_cursor(AVCodecContext *avctx)
     ctx->cursor_stride = FFALIGN(ctx->cursor_w, 32) * 4;
     cursor_fmt = bytestream2_get_le32(&ctx->gbc);
 
-    if (ctx->cursor_x >= avctx->width || ctx->cursor_y >= avctx->height) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Invalid cursor position (%d.%d outside %dx%d).\n",
-               ctx->cursor_x, ctx->cursor_y, avctx->width, avctx->height);
-        return AVERROR_INVALIDDATA;
-    }
     if (ctx->cursor_w < 1 || ctx->cursor_w > 256 ||
         ctx->cursor_h < 1 || ctx->cursor_h > 256) {
         av_log(avctx, AV_LOG_ERROR,
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to