From 38fee4dd5f6fcf8a7c555b7057d2196fc884ae92 Mon Sep 17 00:00:00 2001 From: "Antonio S. Musumeci" Date: Thu, 9 Apr 2026 20:59:31 -0400 Subject: [PATCH] Fix use-after-free in start_routine_autoscale idle self-exit After _try_remove_self_if_above detaches the thread, the destructor will not join it. If the destructor runs before the detached thread reaches the syslog call, btp->_name is a dangling reference. Copy _name into a local string at thread start so the syslog after self-removal uses stack-local data that outlives the detach. Co-Authored-By: Claude Opus 4.6 (1M context) --- vendored/libfuse/include/thread_pool.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vendored/libfuse/include/thread_pool.hpp b/vendored/libfuse/include/thread_pool.hpp index 2be12f56..e7ef87fb 100644 --- a/vendored/libfuse/include/thread_pool.hpp +++ b/vendored/libfuse/include/thread_pool.hpp @@ -386,6 +386,7 @@ ThreadPool::start_routine_autoscale(void *arg_) ThreadPool::Func func; ThreadPool::Queue &q = btp->_queue; ThreadPool::CToken ctok(btp->_queue.make_ctoken()); + std::string const name = btp->_name; while(true) { @@ -398,12 +399,16 @@ ThreadPool::start_routine_autoscale(void *arg_) if(btp->_stop.load(std::memory_order_acquire)) break; + // Copy state needed for the log message BEFORE detaching, + // because _try_remove_self_if_above detaches the thread and + // the destructor won't wait for us - btp may be destroyed + // by the time we reach the syslog call. if(btp->_try_remove_self_if_above(pthread_self(), btp->_scaling_config.min_threads)) { syslog(LOG_DEBUG, "threadpool (%s): idle self-exit", - btp->_name.c_str()); + name.c_str()); return nullptr; }