From: Mathieu Desnoyers Date: Thu, 20 Sep 2018 18:11:17 +0000 (-0400) Subject: Fix: race between statedump and library destructor X-Git-Tag: v2.12.0-rc1~72 X-Git-Url: http://git.liburcu.org/?p=lttng-ust.git;a=commitdiff_plain;h=2eb235ecd28828cef90ff371a96cd532e92ba9f6 Fix: race between statedump and library destructor The locking scheme for ust_lock() returns a teardown state (variable lttng_ust_comm_should_quit) which is set by library destructor with lock held. It requires that when ust listener threads use this lock to protect against concurrent accesses to a data structure, in addition to take the lock, they need to check the return value of ust_lock() and skip their critical section entirely if the return value indicates that teardown is ongoing. Iteration over all loaded libraries by lttng_ust_dl_update() starts by iter_begin which grabs the lock, and sets data->cancel state appropriately if teardown is ongoing. Then extract_bin_info_events() uses the data->cancel state to skip over use of the protected structures as needed, but iter_end() fails to take this data->cancel state into account. Therefore, it can access data structures concurrently while their teardown is ongoing which leads to crashes. Fixes: #1169 Signed-off-by: Mathieu Desnoyers --- diff --git a/liblttng-ust/lttng-ust-statedump.c b/liblttng-ust/lttng-ust-statedump.c index efa8a55a..f40b7195 100644 --- a/liblttng-ust/lttng-ust-statedump.c +++ b/liblttng-ust/lttng-ust-statedump.c @@ -414,6 +414,8 @@ void iter_end(struct dl_iterate_data *data, void *ip) { unsigned int i; + if (data->cancel) + goto end; /* * Iterate on hash table. * For each marked, traced, do nothing. @@ -441,6 +443,7 @@ void iter_end(struct dl_iterate_data *data, void *ip) } } } +end: ust_unlock(); }