From 7ecd0286644590c4214688c8dc1d4bd28f28eafd Mon Sep 17 00:00:00 2001 From: Conn O'Griofa Date: Sun, 28 Jun 2026 15:45:45 +0100 Subject: [PATCH] fix(video): avoid UAF crashes during video reinit (reproducible on Vulkan) (#5346) --- src/video.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/video.cpp b/src/video.cpp index 971e38308..08f9c99c8 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -2389,17 +2389,6 @@ namespace video { } while (true) { - // Break out of the encoding loop if any of the following are true: - // a) The stream is ending - // b) Sunshine is quitting - // c) The capture side is waiting to reinit and we've encoded at least one frame - // - // If we have to reinit before we have received any captured frames, we will encode - // the blank dummy frame just to let Moonlight know that we're alive. - if (shutdown_event->peek() || !images->running() || (reinit_event.peek() && frame_nr > 1)) { - break; - } - bool requested_idr_frame = false; while (invalidate_ref_frames_events->peek()) { @@ -2432,6 +2421,20 @@ namespace video { } } + // Break out of the encoding loop if any of the following are true: + // a) The stream is ending + // b) Sunshine is quitting + // c) The capture side is waiting to reinit and we've encoded at least one frame + // + // If we have to reinit before we have received any captured frames, we will encode + // the blank dummy frame just to let Moonlight know that we're alive. + // + // Ensure that this check occurs as close as possible to the encode call to prevent packets + // in flight after encoder teardown. + if (shutdown_event->peek() || !images->running() || (reinit_event.peek() && frame_nr > 1)) { + break; + } + if (encode(frame_nr++, *session, packets, channel_data, frame_timestamp)) { BOOST_LOG(error) << "Could not encode video packet"sv; return;