]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Nov 2019 10:45:52 +0000 (11:45 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Nov 2019 10:45:52 +0000 (11:45 +0100)
added patches:
cpufreq-add-null-checks-to-show-and-store-methods-of-cpufreq.patch
media-usbvision-fix-races-among-open-close-and-disconnect.patch
media-vivid-fix-wrong-locking-that-causes-race-conditions-on-streaming-stop.patch
media-vivid-set-vid_cap_streaming-and-vid_out_streaming-to-true.patch

queue-4.19/cpufreq-add-null-checks-to-show-and-store-methods-of-cpufreq.patch [new file with mode: 0644]
queue-4.19/media-usbvision-fix-races-among-open-close-and-disconnect.patch [new file with mode: 0644]
queue-4.19/media-vivid-fix-wrong-locking-that-causes-race-conditions-on-streaming-stop.patch [new file with mode: 0644]
queue-4.19/media-vivid-set-vid_cap_streaming-and-vid_out_streaming-to-true.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/cpufreq-add-null-checks-to-show-and-store-methods-of-cpufreq.patch b/queue-4.19/cpufreq-add-null-checks-to-show-and-store-methods-of-cpufreq.patch
new file mode 100644 (file)
index 0000000..9f06d04
--- /dev/null
@@ -0,0 +1,56 @@
+From e6e8df07268c1f75dd9215536e2ce4587b70f977 Mon Sep 17 00:00:00 2001
+From: Kai Shen <shenkai8@huawei.com>
+Date: Thu, 7 Nov 2019 05:08:17 +0000
+Subject: cpufreq: Add NULL checks to show() and store() methods of cpufreq
+
+From: Kai Shen <shenkai8@huawei.com>
+
+commit e6e8df07268c1f75dd9215536e2ce4587b70f977 upstream.
+
+Add NULL checks to show() and store() in cpufreq.c to avoid attempts
+to invoke a NULL callback.
+
+Though some interfaces of cpufreq are set as read-only, users can
+still get write permission using chmod which can lead to a kernel
+crash, as follows:
+
+chmod +w /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
+echo 1 >  /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
+
+This bug was found in linux 4.19.
+
+Signed-off-by: Kai Shen <shenkai8@huawei.com>
+Reported-by: Feilong Lin <linfeilong@huawei.com>
+Reviewed-by: Feilong Lin <linfeilong@huawei.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+[ rjw: Subject & changelog ]
+Cc: All applicable <stable@vger.kernel.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/cpufreq/cpufreq.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -909,6 +909,9 @@ static ssize_t show(struct kobject *kobj
+       struct freq_attr *fattr = to_attr(attr);
+       ssize_t ret;
++      if (!fattr->show)
++              return -EIO;
++
+       down_read(&policy->rwsem);
+       ret = fattr->show(policy, buf);
+       up_read(&policy->rwsem);
+@@ -923,6 +926,9 @@ static ssize_t store(struct kobject *kob
+       struct freq_attr *fattr = to_attr(attr);
+       ssize_t ret = -EINVAL;
++      if (!fattr->store)
++              return -EIO;
++
+       /*
+        * cpus_read_trylock() is used here to work around a circular lock
+        * dependency problem with respect to the cpufreq_register_driver().
diff --git a/queue-4.19/media-usbvision-fix-races-among-open-close-and-disconnect.patch b/queue-4.19/media-usbvision-fix-races-among-open-close-and-disconnect.patch
new file mode 100644 (file)
index 0000000..4a177b7
--- /dev/null
@@ -0,0 +1,131 @@
+From 9e08117c9d4efc1e1bc6fce83dab856d9fd284b6 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Mon, 7 Oct 2019 12:09:53 -0300
+Subject: media: usbvision: Fix races among open, close, and disconnect
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 9e08117c9d4efc1e1bc6fce83dab856d9fd284b6 upstream.
+
+Visual inspection of the usbvision driver shows that it suffers from
+three races between its open, close, and disconnect handlers.  In
+particular, the driver is careful to update its usbvision->user and
+usbvision->remove_pending flags while holding the private mutex, but:
+
+       usbvision_v4l2_close() and usbvision_radio_close() don't hold
+       the mutex while they check the value of
+       usbvision->remove_pending;
+
+       usbvision_disconnect() doesn't hold the mutex while checking
+       the value of usbvision->user; and
+
+       also, usbvision_v4l2_open() and usbvision_radio_open() don't
+       check whether the device has been unplugged before allowing
+       the user to open the device files.
+
+Each of these can potentially lead to usbvision_release() being called
+twice and use-after-free errors.
+
+This patch fixes the races by reading the flags while the mutex is
+still held and checking for pending removes before allowing an open to
+succeed.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: <stable@vger.kernel.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/usbvision/usbvision-video.c |   21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/usb/usbvision/usbvision-video.c
++++ b/drivers/media/usb/usbvision/usbvision-video.c
+@@ -327,6 +327,10 @@ static int usbvision_v4l2_open(struct fi
+       if (mutex_lock_interruptible(&usbvision->v4l2_lock))
+               return -ERESTARTSYS;
++      if (usbvision->remove_pending) {
++              err_code = -ENODEV;
++              goto unlock;
++      }
+       if (usbvision->user) {
+               err_code = -EBUSY;
+       } else {
+@@ -390,6 +394,7 @@ unlock:
+ static int usbvision_v4l2_close(struct file *file)
+ {
+       struct usb_usbvision *usbvision = video_drvdata(file);
++      int r;
+       PDEBUG(DBG_IO, "close");
+@@ -404,9 +409,10 @@ static int usbvision_v4l2_close(struct f
+       usbvision_scratch_free(usbvision);
+       usbvision->user--;
++      r = usbvision->remove_pending;
+       mutex_unlock(&usbvision->v4l2_lock);
+-      if (usbvision->remove_pending) {
++      if (r) {
+               printk(KERN_INFO "%s: Final disconnect\n", __func__);
+               usbvision_release(usbvision);
+               return 0;
+@@ -1090,6 +1096,11 @@ static int usbvision_radio_open(struct f
+       if (mutex_lock_interruptible(&usbvision->v4l2_lock))
+               return -ERESTARTSYS;
++
++      if (usbvision->remove_pending) {
++              err_code = -ENODEV;
++              goto out;
++      }
+       err_code = v4l2_fh_open(file);
+       if (err_code)
+               goto out;
+@@ -1122,6 +1133,7 @@ out:
+ static int usbvision_radio_close(struct file *file)
+ {
+       struct usb_usbvision *usbvision = video_drvdata(file);
++      int r;
+       PDEBUG(DBG_IO, "");
+@@ -1134,9 +1146,10 @@ static int usbvision_radio_close(struct
+       usbvision_audio_off(usbvision);
+       usbvision->radio = 0;
+       usbvision->user--;
++      r = usbvision->remove_pending;
+       mutex_unlock(&usbvision->v4l2_lock);
+-      if (usbvision->remove_pending) {
++      if (r) {
+               printk(KERN_INFO "%s: Final disconnect\n", __func__);
+               v4l2_fh_release(file);
+               usbvision_release(usbvision);
+@@ -1562,6 +1575,7 @@ err_usb:
+ static void usbvision_disconnect(struct usb_interface *intf)
+ {
+       struct usb_usbvision *usbvision = to_usbvision(usb_get_intfdata(intf));
++      int u;
+       PDEBUG(DBG_PROBE, "");
+@@ -1578,13 +1592,14 @@ static void usbvision_disconnect(struct
+       v4l2_device_disconnect(&usbvision->v4l2_dev);
+       usbvision_i2c_unregister(usbvision);
+       usbvision->remove_pending = 1;  /* Now all ISO data will be ignored */
++      u = usbvision->user;
+       usb_put_dev(usbvision->dev);
+       usbvision->dev = NULL;  /* USB device is no more */
+       mutex_unlock(&usbvision->v4l2_lock);
+-      if (usbvision->user) {
++      if (u) {
+               printk(KERN_INFO "%s: In use, disconnect pending\n",
+                      __func__);
+               wake_up_interruptible(&usbvision->wait_frame);
diff --git a/queue-4.19/media-vivid-fix-wrong-locking-that-causes-race-conditions-on-streaming-stop.patch b/queue-4.19/media-vivid-fix-wrong-locking-that-causes-race-conditions-on-streaming-stop.patch
new file mode 100644 (file)
index 0000000..d0d45e1
--- /dev/null
@@ -0,0 +1,122 @@
+From 6dcd5d7a7a29c1e4b8016a06aed78cd650cd8c27 Mon Sep 17 00:00:00 2001
+From: Alexander Popov <alex.popov@linux.com>
+Date: Sun, 3 Nov 2019 23:17:19 +0100
+Subject: media: vivid: Fix wrong locking that causes race conditions on streaming stop
+
+From: Alexander Popov <alex.popov@linux.com>
+
+commit 6dcd5d7a7a29c1e4b8016a06aed78cd650cd8c27 upstream.
+
+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: Alexander Popov <alex.popov@linux.com>
+Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
+Tested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Cc: <stable@vger.kernel.org>      # for v3.18 and up
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/platform/vivid/vivid-kthread-cap.c |    8 +++++---
+ drivers/media/platform/vivid/vivid-kthread-out.c |    8 +++++---
+ drivers/media/platform/vivid/vivid-sdr-cap.c     |    8 +++++---
+ 3 files changed, 15 insertions(+), 9 deletions(-)
+
+--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
++++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
+@@ -765,7 +765,11 @@ static int vivid_thread_vid_cap(void *da
+               if (kthread_should_stop())
+                       break;
+-              mutex_lock(&dev->mutex);
++              if (!mutex_trylock(&dev->mutex)) {
++                      schedule_timeout_uninterruptible(1);
++                      continue;
++              }
++
+               cur_jiffies = jiffies;
+               if (dev->cap_seq_resync) {
+                       dev->jiffies_vid_cap = cur_jiffies;
+@@ -918,8 +922,6 @@ void vivid_stop_generating_vid_cap(struc
+       /* 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);
+ }
+--- a/drivers/media/platform/vivid/vivid-kthread-out.c
++++ b/drivers/media/platform/vivid/vivid-kthread-out.c
+@@ -135,7 +135,11 @@ static int vivid_thread_vid_out(void *da
+               if (kthread_should_stop())
+                       break;
+-              mutex_lock(&dev->mutex);
++              if (!mutex_trylock(&dev->mutex)) {
++                      schedule_timeout_uninterruptible(1);
++                      continue;
++              }
++
+               cur_jiffies = jiffies;
+               if (dev->out_seq_resync) {
+                       dev->jiffies_vid_out = cur_jiffies;
+@@ -289,8 +293,6 @@ void vivid_stop_generating_vid_out(struc
+       /* shutdown control thread */
+       vivid_grab_controls(dev, false);
+-      mutex_unlock(&dev->mutex);
+       kthread_stop(dev->kthread_vid_out);
+       dev->kthread_vid_out = NULL;
+-      mutex_lock(&dev->mutex);
+ }
+--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
++++ b/drivers/media/platform/vivid/vivid-sdr-cap.c
+@@ -137,7 +137,11 @@ static int vivid_thread_sdr_cap(void *da
+               if (kthread_should_stop())
+                       break;
+-              mutex_lock(&dev->mutex);
++              if (!mutex_trylock(&dev->mutex)) {
++                      schedule_timeout_uninterruptible(1);
++                      continue;
++              }
++
+               cur_jiffies = jiffies;
+               if (dev->sdr_cap_seq_resync) {
+                       dev->jiffies_sdr_cap = cur_jiffies;
+@@ -297,10 +301,8 @@ static void sdr_cap_stop_streaming(struc
+       }
+       /* shutdown control thread */
+-      mutex_unlock(&dev->mutex);
+       kthread_stop(dev->kthread_sdr_cap);
+       dev->kthread_sdr_cap = NULL;
+-      mutex_lock(&dev->mutex);
+ }
+ const struct vb2_ops vivid_sdr_cap_qops = {
diff --git a/queue-4.19/media-vivid-set-vid_cap_streaming-and-vid_out_streaming-to-true.patch b/queue-4.19/media-vivid-set-vid_cap_streaming-and-vid_out_streaming-to-true.patch
new file mode 100644 (file)
index 0000000..85091e5
--- /dev/null
@@ -0,0 +1,52 @@
+From b4add02d2236fd5f568db141cfd8eb4290972eb3 Mon Sep 17 00:00:00 2001
+From: Vandana BN <bnvandana@gmail.com>
+Date: Mon, 9 Sep 2019 06:43:31 -0300
+Subject: media: vivid: Set vid_cap_streaming and vid_out_streaming to true
+
+From: Vandana BN <bnvandana@gmail.com>
+
+commit b4add02d2236fd5f568db141cfd8eb4290972eb3 upstream.
+
+When vbi stream is started, followed by video streaming,
+the vid_cap_streaming and vid_out_streaming were not being set to true,
+which would cause the video stream to stop when vbi stream is stopped.
+This patch allows to set vid_cap_streaming and vid_out_streaming to true.
+According to Hans Verkuil it appears that these 'if (dev->kthread_vid_cap)'
+checks are a left-over from the original vivid development and should never
+have been there.
+
+Signed-off-by: Vandana BN <bnvandana@gmail.com>
+Cc: <stable@vger.kernel.org>      # for v3.18 and up
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/platform/vivid/vivid-vid-cap.c |    3 ---
+ drivers/media/platform/vivid/vivid-vid-out.c |    3 ---
+ 2 files changed, 6 deletions(-)
+
+--- a/drivers/media/platform/vivid/vivid-vid-cap.c
++++ b/drivers/media/platform/vivid/vivid-vid-cap.c
+@@ -222,9 +222,6 @@ static int vid_cap_start_streaming(struc
+       if (vb2_is_streaming(&dev->vb_vid_out_q))
+               dev->can_loop_video = vivid_vid_can_loop(dev);
+-      if (dev->kthread_vid_cap)
+-              return 0;
+-
+       dev->vid_cap_seq_count = 0;
+       dprintk(dev, 1, "%s\n", __func__);
+       for (i = 0; i < VIDEO_MAX_FRAME; i++)
+--- a/drivers/media/platform/vivid/vivid-vid-out.c
++++ b/drivers/media/platform/vivid/vivid-vid-out.c
+@@ -146,9 +146,6 @@ static int vid_out_start_streaming(struc
+       if (vb2_is_streaming(&dev->vb_vid_cap_q))
+               dev->can_loop_video = vivid_vid_can_loop(dev);
+-      if (dev->kthread_vid_out)
+-              return 0;
+-
+       dev->vid_out_seq_count = 0;
+       dprintk(dev, 1, "%s\n", __func__);
+       if (dev->start_streaming_error) {
index bda878dd1876c32e9f27ca51bd43442b19cb2e12..531b9c2033960534bfcaf48c38611c97538bb5ba 100644 (file)
@@ -279,4 +279,8 @@ futex-prevent-exit-livelock.patch
 alsa-usb-audio-fix-null-dereference-at-parsing-badd.patch
 nfc-port100-handle-command-failure-cleanly.patch
 net-sysfs-fix-reference-count-leak-in-rx-netdev_queue_add_kobject.patch
+media-vivid-set-vid_cap_streaming-and-vid_out_streaming-to-true.patch
+media-vivid-fix-wrong-locking-that-causes-race-conditions-on-streaming-stop.patch
+media-usbvision-fix-races-among-open-close-and-disconnect.patch
+cpufreq-add-null-checks-to-show-and-store-methods-of-cpufreq.patch
 x86-entry-32-unwind-the-espfix-stack-earlier-on-exception-entry.patch