[CRIU] [PATCH] restorer: fix a race condition between access and unmap to task_entries

Andrey Vagin avagin at openvz.org
Fri Nov 23 06:01:14 EST 2012


If we have tree threads, a following situation can occur:

T2: dec task_entries->nr_in_progress
T3: dec task_entries->nr_in_progress
T3: futex(&task_entries->nr_in_progress, WAKE_UP);
T1: unmap task_entries
T2: futex(&task_entries->nr_in_progress, WAKE_UP) -> EFAULT -> BUG_ON()

This patch adds a futex for synchronising threads.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 pie/restorer.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/pie/restorer.c b/pie/restorer.c
index df6cb73..97bd8a1 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -36,6 +36,7 @@
 	})
 
 static struct task_entries *task_entries;
+static futex_t thread_inprogress;
 
 static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
 {
@@ -237,6 +238,8 @@ long __export_restore_thread(struct thread_restore_args *args)
 
 	futex_wait_while(&task_entries->start, CR_STATE_RESTORE);
 	futex_dec_and_wake(&task_entries->nr_in_progress);
+	futex_wait_while(&task_entries->start, CR_STATE_RESTORE_SIGCHLD);
+	futex_dec_and_wake(&thread_inprogress);
 
 	new_sp = (long)rt_sigframe + 8;
 	asm volatile(
@@ -737,10 +740,15 @@ long __export_restore_task(struct task_restore_core_args *args)
 
 	sys_sigaction(SIGCHLD, &args->sigchld_act, NULL, sizeof(rt_sigset_t));
 
+	futex_set_and_wake(&thread_inprogress, args->nr_threads);
+
 	futex_dec_and_wake(&args->task_entries->nr_in_progress);
 
 	futex_wait_while(&args->task_entries->start, CR_STATE_RESTORE_SIGCHLD);
 
+	/* Wait until children stop to use args->task_entries */
+	futex_wait_while_gt(&thread_inprogress, 1);
+
 	rst_tcp_socks_all(args->rst_tcp_socks, args->rst_tcp_socks_size);
 
 	log_set_fd(-1);
-- 
1.7.11.7



More information about the CRIU mailing list