I mentioned this in https://github.com/intel/thermal_daemon/pull/528/changes#r2867592719 but Claude explains the issue more fully:
int cthd_engine::user_add_sensor(std::string name, std::string path) {
if (path.empty())
thd_engine_mutex.unlock(); // mutex not held here
if (!starts_with(path, "/sys/")) { ... }
std::lock_guard<std::mutex> guard(thd_engine_mutex);
...
}
thd_engine_mutex.unlock() is called before the lock_guard is constructed — the calling thread doesn't hold the mutex. std::mutex::unlock() from a non-owning thread is undefined behavior. Git history (commit 54ee8b8) shows this was introduced when the original pthread_mutex_lock at the top of the function was removed but the matching unlock was retained instead of replaced with return THD_ERROR. Reachable via the AddSensor D-Bus method with an empty path.
I mentioned this in https://github.com/intel/thermal_daemon/pull/528/changes#r2867592719 but Claude explains the issue more fully:
thd_engine_mutex.unlock() is called before the lock_guard is constructed — the calling thread doesn't hold the mutex. std::mutex::unlock() from a non-owning thread is undefined behavior. Git history (commit 54ee8b8) shows this was introduced when the original pthread_mutex_lock at the top of the function was removed but the matching unlock was retained instead of replaced with return THD_ERROR. Reachable via the AddSensor D-Bus method with an empty path.