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:[<ffffffff81080e9c>]  [<ffffffff81080e9c>] __task_pid_nr_ns+0x9c/0x1b0
Call Trace:
[<ffffffffa045ed7d>] task_pid_vnr+0xd/0x10 [scst]
[<ffffffffa0460418>] scst_tgt_dev_thread_pid_show+0x78/0xd0 [scst]
[<ffffffffa045929f>] scst_show+0xf/0x20 [scst]
[<ffffffff81231acb>] sysfs_kf_seq_show+0xab/0x130
[<ffffffff81230176>] kernfs_seq_show+0x26/0x30
[<ffffffff811daf10>] seq_read+0xe0/0x3e0
[<ffffffff81230ab5>] kernfs_fop_read+0x125/0x180
[<ffffffff811b0138>] __vfs_read+0x28/0xe0
[<ffffffff811b07ca>] vfs_read+0x8a/0x140
[<ffffffff811b1669>] SyS_read+0x49/0xb0
[<ffffffff814ffd32>] system_call_fastpath+0x16/0x7a



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6359 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2015-06-17 00:05:29 +00:00
parent b936c23543
commit 76cc064b48

View File

@@ -1958,6 +1958,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;
@@ -1972,10 +1973,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);
}