• Lin Ma's avatar
    nfc: pn533: Fix buggy cleanup order · b8cedb70
    Lin Ma authored
    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: default avatarLin Ma <linma@zju.edu.cn>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    b8cedb70
pn533.c 63.3 KB