1. 15 Sep, 2016 15 commits
  2. 12 Sep, 2016 17 commits
  3. 11 Sep, 2016 1 commit
  4. 07 Sep, 2016 1 commit
    • Ian Abbott's avatar
      staging: comedi: comedi_test: fix timer race conditions · 871499e3
      Ian Abbott authored
      [ 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: default avatarÉric Piel <piel@delmic.com>
      Signed-off-by: default avatarIan Abbott <abbotti@mev.co.uk>
      Cc: Éric Piel <piel@delmic.com>
      Signed-off-by: default avatarSasha Levin <alexander.levin@verizon.com>
      871499e3
  5. 03 Sep, 2016 6 commits