AOSSIE-Org / AOSSIE-Org/PictoPy
BUG: Critical Race Condition in Sync Microservice Watcher Initialization
- Dominant language
- Python
- Stars
- 283
- Forks
- 679
- Avg merge
- 7d 2h
- Merged PRs (30d)
- 3
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### What happened?
**Bug Description:**
A Time-of-Check to Time-of-Use (TOCTOU) race condition exists in sync-microservice/app/utils/watcher.py. This vulnerability allows multiple background watcher threads to be spawned simultaneously, which can lead to duplicated sync events, corrupted global state, and memory leaks.
**Root Cause:** The global variables tracking the watcher state (watcher_thread, watched_folders, folder_id_map) are mutated across asynchronous API requests without thread synchronization (e.g., no threading.Lock()).
Because the startup process involves I/O operations (database and filesystem checks) that yield the Python GIL, if the /start endpoint receives concurrent requests, both requests can bypass the watcher_util_is_watcher_running() check before the first request has a chance to assign the watcher_thread variable. This results in multiple watchfiles processes being initialized and running concurrently over the same directories.
**Proposed Fix**
To enforce thread safety, I propose introducing a global threading.Lock() (e.g., state_lock = threading.Lock()). We can then wrap the critical sections inside watcher_util_start_folder_watcher, watcher_util_stop_folder_watcher, and watcher_util_restart_folder_watcher using a with state_lock: context manager. This will guarantee atomic operations on the global watcher state and completely prevent duplicate thread creation.
### Record
- [x] I agree to follow this project's Code of Conduct
Contributor guide
Assessment
This issue has not been assessed yet.