From 2eb235ecd28828cef90ff371a96cd532e92ba9f6 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 20 Sep 2018 14:11:17 -0400 Subject: [PATCH] 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 --- liblttng-ust/lttng-ust-statedump.c | 3 +++ 1 file changed, 3 insertions(+) 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(); } -- 2.34.1