diff options
author | Lin Ma <linma@zju.edu.cn> | 2022-05-18 18:53:21 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-05-18 13:58:13 +0100 |
commit | b8cedb7093b2d1394cae9b86494cba4b62d3a30a (patch) | |
tree | 1c59ad41974251fe8d257fda44ed834264fb6fa3 /block/blk-mq-sched.h | |
parent | 575fb4fb02b391ed60e5b041acda136f78e7779c (diff) |
nfc: pn533: Fix buggy cleanup order
When removing the pn533 device (i2c or USB), there is a logic error. The
original code first cancels the worker (flush_delayed_work) and then
destroys the workqueue (destroy_workqueue), leaving the timer the last
one to be deleted (del_timer). This result in a possible race condition
in a multi-core preempt-able kernel. That is, if the cleanup
(pn53x_common_clean) is concurrently run with the timer handler
(pn533_listen_mode_timer), the timer can queue the poll_work to the
already destroyed workqueue, causing use-after-free.
This patch reorder the cleanup: it uses the del_timer_sync to make sure
the handler is finished before the routine will destroy the workqueue.
Note that the timer cannot be activated by the worker again.
static void pn533_wq_poll(struct work_struct *work)
...
rc = pn533_send_poll_frame(dev);
if (rc)
return;
if (cur_mod->len == 0 && dev->poll_mod_count > 1)
mod_timer(&dev->listen_timer, ...);
That is, the mod_timer can be called only when pn533_send_poll_frame()
returns no error, which is impossible because the device is detaching
and the lower driver should return ENODEV code.
Signed-off-by: Lin Ma <linma@zju.edu.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'block/blk-mq-sched.h')
0 files changed, 0 insertions, 0 deletions