From af94d2ce4fdaf3a1d771a5b8883c7f98fc0c8129 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 6 May 2015 12:54:29 +0200 Subject: [PATCH] scst: Fix a race between scst_del_threads() and the sysfs API kthread_stop() not only stops a thread but also frees the associated task struct. Avoid that functions that iterate over the thread list can encounter an invalid task structure pointer. This patch fixes the following kernel crash: general protection fault: 0000 [#2] PREEMPT SMP RIP: 0010:[] [] __task_pid_nr_ns+0x9c/0x1b0 Call Trace: [] task_pid_vnr+0xd/0x10 [scst] [] scst_tgt_dev_thread_pid_show+0x78/0xd0 [scst] [] scst_show+0xf/0x20 [scst] [] sysfs_kf_seq_show+0xab/0x130 [] kernfs_seq_show+0x26/0x30 [] seq_read+0xe0/0x3e0 [] kernfs_fop_read+0x125/0x180 [] __vfs_read+0x28/0xe0 [] vfs_read+0x8a/0x140 [] SyS_read+0x49/0xb0 [] system_call_fastpath+0x16/0x7a Signed-off-by: Bart Van Assche --- scst/src/scst_main.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index bf4d6c24a..b730723de 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -1950,6 +1950,7 @@ void scst_del_threads(struct scst_cmd_threads *cmd_threads, int num) thread_list_entry) { if (!ct2->being_stopped) { ct = ct2; + list_del(&ct->thread_list_entry); ct->being_stopped = true; cmd_threads->nr_threads--; break; @@ -1964,10 +1965,6 @@ void scst_del_threads(struct scst_cmd_threads *cmd_threads, int num) if (rc != 0 && rc != -EINTR) TRACE_MGMT_DBG("kthread_stop() failed: %d", rc); - spin_lock(&cmd_threads->thr_lock); - list_del(&ct->thread_list_entry); - spin_unlock(&cmd_threads->thr_lock); - kfree(ct); }