• Alexander Popov's avatar
    media: vivid: Fix wrong locking that causes race conditions on streaming stop · 6dcd5d7a
    Alexander Popov authored
    There is the same incorrect approach to locking implemented in
    vivid_stop_generating_vid_cap(), vivid_stop_generating_vid_out() and
    sdr_cap_stop_streaming().
    
    These functions are called during streaming stopping with vivid_dev.mutex
    locked. And they all do the same mistake while stopping their kthreads,
    which need to lock this mutex as well. See the example from
    vivid_stop_generating_vid_cap():
      /* shutdown control thread */
      vivid_grab_controls(dev, false);
      mutex_unlock(&dev->mutex);
      kthread_stop(dev->kthread_vid_cap);
      dev->kthread_vid_cap = NULL;
      mutex_lock(&dev->mutex);
    
    But when this mutex is unlocked, another vb2_fop_read() can lock it
    instead of vivid_thread_vid_cap() and manipulate the buffer queue.
    That causes a use-after-free access later.
    
    To fix those issues let's:
      1. avoid unlocking the mutex in vivid_stop_generating_vid_cap(),
    vivid_stop_generating_vid_out() and sdr_cap_stop_streaming();
      2. use mutex_trylock() with schedule_timeout_uninterruptible() in
    the loops of the vivid kthread handlers.
    Signed-off-by: default avatarAlexander Popov <alex.popov@linux.com>
    Acked-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Tested-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
    Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
    Cc: <stable@vger.kernel.org>      # for v3.18 and up
    Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
    6dcd5d7a
vivid-kthread-out.c 10.5 KB