Commit 64aeae9808 for ffmpeg

commit 64aeae98089bd6a2e9d46990abbe36fc08c432a7
Author: Michael Niedermayer <michael@niedermayer.cc>
Date:   Wed Oct 14 17:12:12 2026 +0200

    avcodec/lcevcdec: do not enhance a base picture whose format is not the one signalled

    Fixes: NULL pointer dereference
    Fixes: ESfSEfFqsNZe/gray8_hevc_420_10bit_1d.hevc

    Found during triage/review of the security report yOAdvErxaeGg

    NULL pointer dereference Replicated through UnModified FFmpeg with ASAN

    Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 57baaad15b..e1d908fd52 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -101,6 +101,7 @@ typedef struct DecodeContext {
         FFLCEVCContext *ctx;
         int frame;
         enum AVPixelFormat format;
+        enum AVPixelFormat base_format;
         int base_width;
         int base_height;
         int width;
@@ -1665,6 +1666,7 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)

     if (dc->lcevc.frame) {
         ret = ff_lcevc_parse_frame(dc->lcevc.ctx, frame, &dc->lcevc.format,
+                                   &dc->lcevc.base_format,
                                    &dc->lcevc.width, &dc->lcevc.height);
         if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
             return ret;
@@ -1672,7 +1674,8 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
         // force get_buffer2() to allocate the base frame with at least the dimensions
         // of the final enhanced frame, in order to prevent reinitializing the buffer
         // pools unnecessarely
-        if (!ret && dc->lcevc.width && dc->lcevc.height) {
+        if (!ret && dc->lcevc.width && dc->lcevc.height &&
+            frame->format == dc->lcevc.base_format) {
             dc->lcevc.base_width  = frame->width;
             dc->lcevc.base_height = frame->height;
             frame->width  = FFMAX(frame->width,  dc->lcevc.width);
@@ -1742,11 +1745,13 @@ int ff_attach_decode_data(AVCodecContext *avctx, AVFrame *frame)

         if (dc->lcevc.frame) {
             int ret = ff_lcevc_parse_frame(dc->lcevc.ctx, frame, &dc->lcevc.format,
+                                           &dc->lcevc.base_format,
                                            &dc->lcevc.width, &dc->lcevc.height);
             if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
                 return ret;

-            if (!ret && dc->lcevc.width && dc->lcevc.height) {
+            if (!ret && dc->lcevc.width && dc->lcevc.height &&
+                frame->format == dc->lcevc.base_format) {
                 dc->lcevc.base_width  = frame->width;
                 dc->lcevc.base_height = frame->height;
             } else
@@ -2427,6 +2432,7 @@ av_cold void ff_decode_internal_sync(AVCodecContext *dst, const AVCodecContext *
     dst_dc->lcevc.width = src_dc->lcevc.width;
     dst_dc->lcevc.height = src_dc->lcevc.height;
     dst_dc->lcevc.format = src_dc->lcevc.format;
+    dst_dc->lcevc.base_format = src_dc->lcevc.base_format;
 #endif
 }

diff --git a/libavcodec/lcevcdec.c b/libavcodec/lcevcdec.c
index c82aa7229f..3e990c0544 100644
--- a/libavcodec/lcevcdec.c
+++ b/libavcodec/lcevcdec.c
@@ -513,7 +513,8 @@ int ff_lcevc_process(void *logctx, AVFrame *frame)
 }

 int ff_lcevc_parse_frame(FFLCEVCContext *lcevc, const AVFrame *frame,
-                         enum AVPixelFormat *format, int *width, int *height)
+                         enum AVPixelFormat *format, enum AVPixelFormat *base_format,
+                         int *width, int *height)
 {
     LCEVCRawProcessBlock *block = NULL;
     const LCEVCRawGlobalConfig *gc;
@@ -536,6 +537,7 @@ int ff_lcevc_parse_frame(FFLCEVCContext *lcevc, const AVFrame *frame,
     gc = block->payload;

     *format = ff_lcevc_depth_type[gc->enhancement_depth_type][gc->chroma_sampling_type];
+    *base_format = ff_lcevc_depth_type[gc->base_depth_type][gc->chroma_sampling_type];
     if (gc->resolution_type < 63) {
         *width  = ff_lcevc_resolution_type[gc->resolution_type].width;
         *height = ff_lcevc_resolution_type[gc->resolution_type].height;
diff --git a/libavcodec/lcevcdec.h b/libavcodec/lcevcdec.h
index b757acc3f9..91b58d15a5 100644
--- a/libavcodec/lcevcdec.h
+++ b/libavcodec/lcevcdec.h
@@ -66,6 +66,7 @@ typedef struct FFLCEVCFrame {
 int ff_lcevc_alloc(FFLCEVCContext **plcevc, AVDictionary **options, int loglevel);
 int ff_lcevc_process(void *logctx, struct AVFrame *frame);
 int ff_lcevc_parse_frame(FFLCEVCContext *lcevc, const struct AVFrame *frame,
-                         enum AVPixelFormat *format, int *width, int *height);
+                         enum AVPixelFormat *format, enum AVPixelFormat *base_format,
+                         int *width, int *height);

 #endif /* AVCODEC_LCEVCDEC_H */