]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Jan 2024 18:53:10 +0000 (10:53 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Jan 2024 18:53:10 +0000 (10:53 -0800)
added patches:
usb-mon-fix-atomicity-violation-in-mon_bin_vma_fault.patch

queue-4.19/series
queue-4.19/usb-mon-fix-atomicity-violation-in-mon_bin_vma_fault.patch [new file with mode: 0644]

index 168afbdcc8444de41de6d58f680857ba8854d77e..53e30411784ceebb1157d3fcc8de4dfb10391bb9 100644 (file)
@@ -123,3 +123,4 @@ revert-usb-dwc3-don-t-reset-device-side-if-dwc3-was-configured-as-host-only.patc
 usb-chipidea-wait-controller-resume-finished-for-wakeup-irq.patch
 revert-usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch
 usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch
+usb-mon-fix-atomicity-violation-in-mon_bin_vma_fault.patch
diff --git a/queue-4.19/usb-mon-fix-atomicity-violation-in-mon_bin_vma_fault.patch b/queue-4.19/usb-mon-fix-atomicity-violation-in-mon_bin_vma_fault.patch
new file mode 100644 (file)
index 0000000..27ba6a6
--- /dev/null
@@ -0,0 +1,90 @@
+From 2dd23cc4d0e6aa55cf9fb3b05f2f4165b01de81c Mon Sep 17 00:00:00 2001
+From: Gui-Dong Han <2045gemini@gmail.com>
+Date: Fri, 5 Jan 2024 13:24:12 +0800
+Subject: usb: mon: Fix atomicity violation in mon_bin_vma_fault
+
+From: Gui-Dong Han <2045gemini@gmail.com>
+
+commit 2dd23cc4d0e6aa55cf9fb3b05f2f4165b01de81c upstream.
+
+In mon_bin_vma_fault():
+    offset = vmf->pgoff << PAGE_SHIFT;
+    if (offset >= rp->b_size)
+        return VM_FAULT_SIGBUS;
+    chunk_idx = offset / CHUNK_SIZE;
+    pageptr = rp->b_vec[chunk_idx].pg;
+The code is executed without holding any lock.
+
+In mon_bin_vma_close():
+    spin_lock_irqsave(&rp->b_lock, flags);
+    rp->mmap_active--;
+    spin_unlock_irqrestore(&rp->b_lock, flags);
+
+In mon_bin_ioctl():
+    spin_lock_irqsave(&rp->b_lock, flags);
+    if (rp->mmap_active) {
+        ...
+    } else {
+        ...
+        kfree(rp->b_vec);
+        rp->b_vec  = vec;
+        rp->b_size = size;
+        ...
+    }
+    spin_unlock_irqrestore(&rp->b_lock, flags);
+
+Concurrent execution of mon_bin_vma_fault() with mon_bin_vma_close() and
+mon_bin_ioctl() could lead to atomicity violations. mon_bin_vma_fault()
+accesses rp->b_size and rp->b_vec without locking, risking array
+out-of-bounds access or use-after-free bugs due to possible modifications
+in mon_bin_ioctl().
+
+This possible bug is found by an experimental static analysis tool
+developed by our team, BassCheck[1]. This tool analyzes the locking APIs
+to extract function pairs that can be concurrently executed, and then
+analyzes the instructions in the paired functions to identify possible
+concurrency bugs including data races and atomicity violations. The above
+possible bug is reported when our tool analyzes the source code of
+Linux 6.2.
+
+To address this issue, it is proposed to add a spin lock pair in
+mon_bin_vma_fault() to ensure atomicity. With this patch applied, our tool
+never reports the possible bug, with the kernel configuration allyesconfig
+for x86_64. Due to the lack of associated hardware, we cannot test the
+patch in runtime testing, and just verify it according to the code logic.
+
+[1] https://sites.google.com/view/basscheck/
+
+Fixes: 19e6317d24c2 ("usb: mon: Fix a deadlock in usbmon between ...")
+Cc:  <stable@vger.kernel.org>
+Signed-off-by: Gui-Dong Han <2045gemini@gmail.com>
+Link: https://lore.kernel.org/r/20240105052412.9377-1-2045gemini@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/mon/mon_bin.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/mon/mon_bin.c
++++ b/drivers/usb/mon/mon_bin.c
+@@ -1247,14 +1247,19 @@ static vm_fault_t mon_bin_vma_fault(stru
+       struct mon_reader_bin *rp = vmf->vma->vm_private_data;
+       unsigned long offset, chunk_idx;
+       struct page *pageptr;
++      unsigned long flags;
++      spin_lock_irqsave(&rp->b_lock, flags);
+       offset = vmf->pgoff << PAGE_SHIFT;
+-      if (offset >= rp->b_size)
++      if (offset >= rp->b_size) {
++              spin_unlock_irqrestore(&rp->b_lock, flags);
+               return VM_FAULT_SIGBUS;
++      }
+       chunk_idx = offset / CHUNK_SIZE;
+       pageptr = rp->b_vec[chunk_idx].pg;
+       get_page(pageptr);
+       vmf->page = pageptr;
++      spin_unlock_irqrestore(&rp->b_lock, flags);
+       return 0;
+ }