-
-
Notifications
You must be signed in to change notification settings - Fork 257
Fix race conditions in stage surface data handling and shared state access #716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Co-authored-by: umireon <[email protected]>
Co-authored-by: umireon <[email protected]>
Race Condition Analysis and FixesThis document describes race conditions that were identified and fixed in the OBS Background Removal plugin. Critical Race Conditions Fixed1. Use-After-Unmap in Stage Surface Data AccessLocation: Description: Original Code: {
std::lock_guard<std::mutex> lock(tf->inputBGRALock);
tf->inputBGRA = cv::Mat(height, width, CV_8UC4, video_data, linesize);
}
gs_stagesurface_unmap(tf->stagesurface);Issue:
Fix: {
std::lock_guard<std::mutex> lock(tf->inputBGRALock);
// Create a temporary Mat that wraps the video_data pointer
cv::Mat temp(height, width, CV_8UC4, video_data, linesize);
// Clone the data to ensure tf->inputBGRA has its own copy
// This prevents use-after-unmap race condition
tf->inputBGRA = temp.clone();
}
gs_stagesurface_unmap(tf->stagesurface);Impact:
2. Non-Atomic Access to isDisabled FlagLocation: Description: Threads Accessing isDisabled:
Original Code: bool isDisabled;Issue:
Fix: std::atomic<bool> isDisabled{false};Impact:
Minor Race Conditions (Documented but Not Fixed)3. Model Pointer Check Without Mutex (TOCTOU)Location: Description: Code: // In background_filter_video_tick()
if (!tf->model) { // Line 463 - no lock held
obs_log(LOG_ERROR, "Model is not initialized");
return;
}
// ... later ...
{
std::unique_lock<std::mutex> lock(tf->modelMutex); // Line 512
processImageForBackground(tf, imageBGRA, backgroundMask);
}Analysis:
Recommendation:
However, given the protection from Thread Safety AnalysisThread ModelThe plugin operates with multiple threads:
Mutex Usage
Thread-Safe Members
Testing RecommendationsTo verify these fixes:
References
|
|
@royshil Copilot analyzed the race conditions. Please review. |
|
I think this change is valid one. |
royshil
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks legit
…ccess (royshil#716) * Initial plan * Fix race condition: Clone stage surface data before unmap Co-authored-by: umireon <[email protected]> * Fix race condition: Make isDisabled atomic and add documentation Co-authored-by: umireon <[email protected]> * Delete RACE-CONDITIONS.md --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: umireon <[email protected]> Co-authored-by: Kaito Udagawa <[email protected]>
Two race conditions cause undefined behavior: (1) cv::Mat references unmapped stage surface memory accessed by other threads, (2) plain bool
isDisabledaccessed without synchronization across multiple threads.Changes
Use-after-unmap in stage surface handling
File:
src/obs-utils/obs-utils.cppThe video render thread creates a cv::Mat wrapping mapped stage surface memory, then immediately unmaps it. The video tick thread then accesses this invalid pointer via
clone().Non-atomic shared state
File:
src/FilterData.hThe
isDisabledflag is written by the settings/activate/deactivate threads and read by video tick/render threads without synchronization.Documentation
Added
docs/RACE-CONDITIONS.mdwith thread model analysis, synchronization patterns, and a minor TOCTOU issue with model pointer access (mitigated by atomicisDisabled).Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.