This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch release/4.3
in repository ffmpeg.

commit 415ed8bb0936a81737269d8428b55f7cb19f664f
Author:     Andreas Rheinhardt <[email protected]>
AuthorDate: Fri Aug 12 03:05:34 2022 +0200
Commit:     James Almer <[email protected]>
CommitDate: Fri Jan 2 21:58:51 2026 +0000

    avcodec/vp9: Fix race when attaching side-data for show-existing frame
    
    When outputting a show-existing frame, the VP9 decoder simply
    created a reference to said frame and returned it immediately to
    the caller, without waiting for it to have finished decoding.
    In case of frame-threading it is possible for the frame to
    only be decoded while it was waiting to be output.
    This is normally benign.
    
    But there is one case where it is not: If the user wants
    video encoding parameters to be exported, said side data
    will only be attached to the src AVFrame at the end of
    decoding the frame that is actually being shown. Without
    synchronisation adding said side data in the decoder thread
    and the reads in av_frame_ref() in the output thread
    constitute a data race. This happens e.g. when using the
    venc_data_dump tool with vp90-2-10-show-existing-frame.webm
    from the FATE-suite.
    
    Fix this by actually waiting for the frame to be output.
    
    Backport comment: in 7.1 there was a switch to ProgressFrames
    (7bd3b737163), so there was the need to convert the calls back to
    ThreadFrames calls.
    
    Fixes: CVE-2024-36615
    
    Signed-off-by: Andreas Rheinhardt <[email protected]>
    (cherry picked from commit 0ba058579f332b3060d8470a04ddd3fbf305be61)
    Signed-off-by: Carlos Henrique Lima Melara <[email protected]>
---
 libavcodec/vp9.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index fd0bab14a2..bc58d647ab 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -1566,6 +1566,8 @@ static int vp9_decode_frame(AVCodecContext *avctx, void 
*frame,
             av_log(avctx, AV_LOG_ERROR, "Requested reference %d not 
available\n", ref);
             return AVERROR_INVALIDDATA;
         }
+        ff_thread_await_progress(&s->s.refs[ref], INT_MAX, 0);
+
         if ((ret = av_frame_ref(frame, s->s.refs[ref].f)) < 0)
             return ret;
         ((AVFrame *)frame)->pts = pkt->pts;
@@ -1732,10 +1734,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
 #endif
         {
             ret = decode_tiles(avctx, data, size);
-            if (ret < 0) {
-                ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 
0);
-                return ret;
-            }
+            if (ret < 0)
+                goto fail;
         }
 
         // Sum all counts fields into td[0].counts for tile threading
@@ -1749,18 +1749,19 @@ FF_ENABLE_DEPRECATION_WARNINGS
             ff_thread_finish_setup(avctx);
         }
     } while (s->pass++ == 1);
-    ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
 
     if (s->td->error_info < 0) {
         av_log(avctx, AV_LOG_ERROR, "Failed to decode tile data\n");
         s->td->error_info = 0;
-        return AVERROR_INVALIDDATA;
+        ret = AVERROR_INVALIDDATA;
+        goto fail;
     }
     if (avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS) {
         ret = vp9_export_enc_params(s, &s->s.frames[CUR_FRAME]);
         if (ret < 0)
-            return ret;
+            goto fail;
     }
+    ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
 
 finish:
     // ref frame setup
@@ -1779,6 +1780,9 @@ finish:
     }
 
     return pkt->size;
+fail:
+    ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
+    return ret;
 }
 
 static void vp9_decode_flush(AVCodecContext *avctx)

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

Reply via email to