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

Git pushed a commit to branch master
in repository ffmpeg.

commit 04888287b38ef4b45351fad76cb32c2510628fe7
Author:     Niklas Haas <[email protected]>
AuthorDate: Fri Dec 19 15:59:23 2025 +0100
Commit:     Niklas Haas <[email protected]>
CommitDate: Sat May 23 08:41:12 2026 +0000

    fftools/ffmpeg_sched: fix sch_stop() and schedule_update_locked() race
    
    schedule_update_locked() is supposed to be a no-op when `sch->terminate`
    is 1. However, there is a TOCTOU error here, where a different thread may
    currently be executing schedule_update_locked(), having successfully passed
    the sch->terminate check but without actually updating the choke status.
    
    This does not matter for the current code, but will matter with the 
following
    commit, where it creates the theoretical possibility of a race where 
sch_stop()
    is trying to choke the demuxers (and unchoke the decoders) while
    schedule_update_locked() is simultaneously trying to choke the decoders,
    leading to a deadlock if the last decoder is left choked and unable to
    propagate EOF downstream.
    
    The cleanest solution is to just take the scheduler lock while updating the
    choke status here. This ensures that any other schedule_update_locked() 
calls
    will have completed.
    
    Sponsored-by: nxtedition AB
    Signed-off-by: Niklas Haas <[email protected]>
---
 fftools/ffmpeg_sched.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fftools/ffmpeg_sched.c b/fftools/ffmpeg_sched.c
index b01cf8b6ad..ac95ece794 100644
--- a/fftools/ffmpeg_sched.c
+++ b/fftools/ffmpeg_sched.c
@@ -2756,6 +2756,10 @@ int sch_stop(Scheduler *sch, int64_t *finish_ts)
 
     atomic_store(&sch->terminate, 1);
 
+    // Ensure no other thread is currently in schedule_update_locked while
+    // we are choking all demuxers
+    pthread_mutex_lock(&sch->schedule_lock);
+
     for (unsigned type = 0; type < 2; type++)
         for (unsigned i = 0; i < (type ? sch->nb_demux : sch->nb_filters); 
i++) {
             SchWaiter *w = type ? &sch->demux[i].waiter : 
&sch->filters[i].waiter;
@@ -2764,6 +2768,8 @@ int sch_stop(Scheduler *sch, int64_t *finish_ts)
                 choke_demux(sch, i, 0); // unfreeze to allow draining
         }
 
+    pthread_mutex_unlock(&sch->schedule_lock);
+
     for (unsigned i = 0; i < sch->nb_demux; i++) {
         SchDemux *d = &sch->demux[i];
 

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

Reply via email to