staging: comedi: comedi_test: fix timer race conditions
[ commit 403fe7f3 upstream. Patch is cut down a bit from upstream patch, as upstream patch fixed parts that don't exist in this version. Also, some identifiers were renamed, so patch description has been edited accordingly -- Ian Abbott ] Commit 73e0e4df ("staging: comedi: comedi_test: fix timer lock-up") fixed a lock-up in the timer routine `waveform_ai_interrupt()` caused by commit 24051247 ("staging: comedi: comedi_test: use comedi_handle_events()"). However, it introduced a race condition that can result in the timer routine misbehaving, such as accessing freed memory or dereferencing a NULL pointer. 73e0... changed the timer routine to do nothing unless a `WAVEFORM_AI_RUNNING` flag was set, and changed `waveform_ai_cancel()` to clear the flag and replace a call to `del_timer_sync()` with a call to `del_timer()`. `waveform_ai_cancel()` may be called from the timer routine itself (via `comedi_handle_events()`), or from `do_cancel()`. (`do_cancel()` is called as a result of a file operation (usually a `COMEDI_CANCEL` ioctl command, or a release), or during device removal.) When called from `do_cancel()`, the call to `waveform_ai_cancel()` is followed by a call to `do_become_nonbusy()`, which frees up stuff for the current asynchronous command under the assumption that it is now safe to do so. The race condition occurs when the timer routine `waveform_ai_interrupt()` checks the `WAVEFORM_AI_RUNNING` flag just before it is cleared by `waveform_ai_cancel()`, and is still running during the call to `do_become_nonbusy()`. In particular, it can lead to a NULL pointer dereference because `do_become_nonbusy()` frees `async->cmd.chanlist` and sets it to `NULL`, but `waveform_ai_interrupt()` dereferences it. Fix the race by calling `del_timer_sync()` instead of `del_timer()` in `waveform_ai_cancel()` when not in an interrupt context. The only time `waveform_ai_cancel()` is called in an interrupt context is when it is called from the timer routine itself, via `comedi_handle_events()`. There is no longer any need for the `WAVEFORM_AI_RUNNING` flag, so get rid of it. Fixes: 73e0e4df ("staging: comedi: comedi_test: fix timer lock-up") Reported-by: Éric Piel <piel@delmic.com> Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Cc: Éric Piel <piel@delmic.com> Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Showing
Please register or sign in to comment