diff --git a/ChangeLog b/ChangeLog index 709f747561..1846832c4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ Changes in version 0.2.1.16-?? - 2009-??-?? - Don't warn users about low port and hibernation mix when they provide a *ListenAddress directive to fix that. Bugfix on 0.2.1.15-rc. + - Fix a race condition that could cause crashes or memory + corruption when running as a server with a controller listening + for log messages. o Minor bugfixes (on 0.2.1.x): - When switching back and forth between bridge mode, do not start diff --git a/src/common/compat.c b/src/common/compat.c index 35bb3a9ad3..d62b1ce1f4 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -2076,6 +2076,7 @@ tor_threads_init(void) pthread_mutexattr_init(&attr_reentrant); pthread_mutexattr_settype(&attr_reentrant, PTHREAD_MUTEX_RECURSIVE); threads_initialized = 1; + set_main_thread(); } } #elif defined(USE_WIN32_THREADS) @@ -2168,9 +2169,27 @@ tor_threads_init(void) #if 0 cond_event_tls_index = TlsAlloc(); #endif + set_main_thread(); } #endif +/** Identity of the "main" thread */ +static unsigned long main_thread_id = -1; + +/** Start considering the current thread to be the 'main thread'. This has + * no effect on anything besides in_main_thread(). */ +void +set_main_thread(void) +{ + main_thread_id = tor_get_thread_id(); +} +/** Return true iff called from the main thread. */ +int +in_main_thread(void) +{ + return main_thread_id == tor_get_thread_id(); +} + /** * On Windows, WSAEWOULDBLOCK is not always correct: when you see it, * you need to ask the socket for its actual errno. Also, you need to diff --git a/src/common/compat.h b/src/common/compat.h index edc38faf64..4d5a016cf2 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -522,6 +522,9 @@ void tor_threads_init(void); #define tor_threads_init() STMT_NIL #endif +void set_main_thread(void); +int in_main_thread(void); + #ifdef TOR_IS_MULTITHREADED #if 0 typedef struct tor_cond_t tor_cond_t; diff --git a/src/common/util.c b/src/common/util.c index a3338b1d18..7b9e5eb562 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -2480,6 +2480,8 @@ start_daemon(void) if (fork() != 0) { exit(0); } + set_main_thread(); /* We are now the main thread. */ + return; } } diff --git a/src/or/control.c b/src/or/control.c index 8ded31574c..486ccc4c75 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -3367,6 +3367,11 @@ control_event_logmsg(int severity, uint32_t domain, const char *msg) { int event; + /* Don't even think of trying to add stuff to a buffer from a cpuworker + * thread. */ + if (! in_main_thread()) + return; + if (disable_log_messages) return;