]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Jul 2022 11:26:27 +0000 (13:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Jul 2022 11:26:27 +0000 (13:26 +0200)
added patches:
net-rose-fix-uaf-bug-caused-by-rose_t0timer_expiry.patch
usbnet-fix-memory-leak-in-error-case.patch

queue-5.4/net-rose-fix-uaf-bug-caused-by-rose_t0timer_expiry.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/usbnet-fix-memory-leak-in-error-case.patch [new file with mode: 0644]

diff --git a/queue-5.4/net-rose-fix-uaf-bug-caused-by-rose_t0timer_expiry.patch b/queue-5.4/net-rose-fix-uaf-bug-caused-by-rose_t0timer_expiry.patch
new file mode 100644 (file)
index 0000000..ff4c565
--- /dev/null
@@ -0,0 +1,73 @@
+From 148ca04518070910739dfc4eeda765057856403d Mon Sep 17 00:00:00 2001
+From: Duoming Zhou <duoming@zju.edu.cn>
+Date: Tue, 5 Jul 2022 20:56:10 +0800
+Subject: net: rose: fix UAF bug caused by rose_t0timer_expiry
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+commit 148ca04518070910739dfc4eeda765057856403d upstream.
+
+There are UAF bugs caused by rose_t0timer_expiry(). The
+root cause is that del_timer() could not stop the timer
+handler that is running and there is no synchronization.
+One of the race conditions is shown below:
+
+    (thread 1)             |        (thread 2)
+                           | rose_device_event
+                           |   rose_rt_device_down
+                           |     rose_remove_neigh
+rose_t0timer_expiry        |       rose_stop_t0timer(rose_neigh)
+  ...                      |         del_timer(&neigh->t0timer)
+                           |         kfree(rose_neigh) //[1]FREE
+  neigh->dce_mode //[2]USE |
+
+The rose_neigh is deallocated in position [1] and use in
+position [2].
+
+The crash trace triggered by POC is like below:
+
+BUG: KASAN: use-after-free in expire_timers+0x144/0x320
+Write of size 8 at addr ffff888009b19658 by task swapper/0/0
+...
+Call Trace:
+ <IRQ>
+ dump_stack_lvl+0xbf/0xee
+ print_address_description+0x7b/0x440
+ print_report+0x101/0x230
+ ? expire_timers+0x144/0x320
+ kasan_report+0xed/0x120
+ ? expire_timers+0x144/0x320
+ expire_timers+0x144/0x320
+ __run_timers+0x3ff/0x4d0
+ run_timer_softirq+0x41/0x80
+ __do_softirq+0x233/0x544
+ ...
+
+This patch changes rose_stop_ftimer() and rose_stop_t0timer()
+in rose_remove_neigh() to del_timer_sync() in order that the
+timer handler could be finished before the resources such as
+rose_neigh and so on are deallocated. As a result, the UAF
+bugs could be mitigated.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Link: https://lore.kernel.org/r/20220705125610.77971-1-duoming@zju.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rose/rose_route.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -227,8 +227,8 @@ static void rose_remove_neigh(struct ros
+ {
+       struct rose_neigh *s;
+-      rose_stop_ftimer(rose_neigh);
+-      rose_stop_t0timer(rose_neigh);
++      del_timer_sync(&rose_neigh->ftimer);
++      del_timer_sync(&rose_neigh->t0timer);
+       skb_queue_purge(&rose_neigh->queue);
index e3b34df9e57908d1f3949ba751654206e1029ecd..71c22a97ba284df053f0c43a1f00adfd2e83409a 100644 (file)
@@ -3,3 +3,5 @@ mm-slub-add-missing-tid-updates-on-slab-deactivation.patch
 can-bcm-use-call_rcu-instead-of-costly-synchronize_rcu.patch
 can-grcan-grcan_probe-remove-extra-of_node_get.patch
 can-gs_usb-gs_usb_open-close-fix-memory-leak.patch
+usbnet-fix-memory-leak-in-error-case.patch
+net-rose-fix-uaf-bug-caused-by-rose_t0timer_expiry.patch
diff --git a/queue-5.4/usbnet-fix-memory-leak-in-error-case.patch b/queue-5.4/usbnet-fix-memory-leak-in-error-case.patch
new file mode 100644 (file)
index 0000000..e680d77
--- /dev/null
@@ -0,0 +1,69 @@
+From b55a21b764c1e182014630fa5486d717484ac58f Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Tue, 5 Jul 2022 14:53:51 +0200
+Subject: usbnet: fix memory leak in error case
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit b55a21b764c1e182014630fa5486d717484ac58f upstream.
+
+usbnet_write_cmd_async() mixed up which buffers
+need to be freed in which error case.
+
+v2: add Fixes tag
+v3: fix uninitialized buf pointer
+
+Fixes: 877bd862f32b8 ("usbnet: introduce usbnet 3 command helpers")
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Link: https://lore.kernel.org/r/20220705125351.17309-1-oneukum@suse.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/usbnet.c |   17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -2120,7 +2120,7 @@ static void usbnet_async_cmd_cb(struct u
+ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
+                          u16 value, u16 index, const void *data, u16 size)
+ {
+-      struct usb_ctrlrequest *req = NULL;
++      struct usb_ctrlrequest *req;
+       struct urb *urb;
+       int err = -ENOMEM;
+       void *buf = NULL;
+@@ -2138,7 +2138,7 @@ int usbnet_write_cmd_async(struct usbnet
+               if (!buf) {
+                       netdev_err(dev->net, "Error allocating buffer"
+                                  " in %s!\n", __func__);
+-                      goto fail_free;
++                      goto fail_free_urb;
+               }
+       }
+@@ -2162,14 +2162,21 @@ int usbnet_write_cmd_async(struct usbnet
+       if (err < 0) {
+               netdev_err(dev->net, "Error submitting the control"
+                          " message: status=%d\n", err);
+-              goto fail_free;
++              goto fail_free_all;
+       }
+       return 0;
++fail_free_all:
++      kfree(req);
+ fail_free_buf:
+       kfree(buf);
+-fail_free:
+-      kfree(req);
++      /*
++       * avoid a double free
++       * needed because the flag can be set only
++       * after filling the URB
++       */
++      urb->transfer_flags = 0;
++fail_free_urb:
+       usb_free_urb(urb);
+ fail:
+       return err;