mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-19 11:41:26 +00:00
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 Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user