aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>2022-02-07 17:43:23 +0100
committerDenis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>2022-02-08 09:50:48 +0100
commit601056ab853dcaf523625cf6cae397d3ae4b8d0e (patch)
tree3d09273703580c3ec33d71294ed9992aaed38b24
parent12a435ec8234fa05eef3a85a12a916c047801433 (diff)
downloadkernel_replicant_linux-replicant-11.tar.gz
kernel_replicant_linux-replicant-11.tar.bz2
kernel_replicant_linux-replicant-11.zip
If the device is disconnected, we need to make sure that ep->in_urb is not used otherwise we can have a use after free: ------------[ cut here ]------------ WARNING: CPU: 2 PID: 5464 at lib/refcount.c:28 refcount_warn_saturate+0x60/0x134 refcount_t: underflow; use-after-free. CPU: 2 PID: 5464 Comm: ipc-modem Not tainted 5.10.70-977921-g2f5a453af3fc-dirty #77 Hardware name: Samsung Exynos (Flattened Device Tree) Backtrace: [<c099c03c>] (dump_backtrace) from [<c099c260>] (show_stack+0x18/0x1c) r7:00000009 r6:60000013 r5:00000000 r4:c0eae790 [<c099c248>] (show_stack) from [<c09a4d24>] (dump_stack+0x90/0xac) [<c09a4c94>] (dump_stack) from [<c099c9fc>] (__warn+0xac/0xd4) r7:00000009 r6:c3355c34 r5:00000000 r4:00000009 [<c099c950>] (__warn) from [<c099caa4>] (warn_slowpath_fmt+0x80/0xbc) r6:c03d282c r5:0000001c r4:c0bbea9c [<c099ca28>] (warn_slowpath_fmt) from [<c03d282c>] (refcount_warn_saturate+0x60/0x134) r8:c0e95dd0 r7:00000000 r6:00000000 r5:c0e95d98 r4:c5327d80 [<c03d27cc>] (refcount_warn_saturate) from [<c05aabfc>] (usb_free_urb+0x6c/0x70) [<c05aab90>] (usb_free_urb) from [<c059d484>] (sipc_disconnect+0x60/0x68) r5:c0e95d98 r4:c5327c40 [<c059d424>] (sipc_disconnect) from [<c05af7a8>] (usb_unbind_interface+0x8c/0x1e4) r7:00000000 r6:c3564800 r5:00000000 r4:c3564020 [<c05af71c>] (usb_unbind_interface) from [<c04c3b64>] (device_release_driver_internal+0xc0/0x1b0) r10:c35648bc r9:c0beeea9 r8:c0eb5780 r7:00000000 r6:c0e95dd0 r5:00000000 r4:c3564020 [<c04c3aa4>] (device_release_driver_internal) from [<c04c3c6c>] (device_release_driver+0x18/0x1c) r7:00000000 r6:c0e96124 r5:c1c39030 r4:c3564020 [<c04c3c54>] (device_release_driver) from [<c04c183c>] (bus_remove_device+0xe4/0x120) [<c04c1758>] (bus_remove_device) from [<c04be43c>] (device_del+0x19c/0x370) r7:00000000 r6:c3564878 r5:c0e8e8f4 r4:c3564020 [<c04be2a0>] (device_del) from [<c05ad1f0>] (usb_disable_device+0x158/0x19c) r10:c35648bc r9:c0beeea9 r8:c0eb5780 r7:00000000 r6:00000000 r5:c3564000 r4:c3564800 [<c05ad098>] (usb_disable_device) from [<c05a2c34>] (usb_disconnect+0x98/0x1dc) r9:c34cc800 r8:00000000 r7:00000000 r6:c3564878 r5:00000000 r4:c3564800 [<c05a2b9c>] (usb_disconnect) from [<c05a2d58>] (usb_disconnect+0x1bc/0x1dc) r10:c34cccbc r9:c3355e20 r8:00000000 r7:c35cec00 r6:c34ccc78 r5:00000001 r4:c34ccc00 [<c05a2b9c>] (usb_disconnect) from [<c09a1394>] (usb_remove_hcd+0xd0/0x1d4) r10:00000004 r9:c3354000 r8:00000000 r7:c161d454 r6:00000001 r5:c2c44cc0 r4:c2c44c00 [<c09a12c4>] (usb_remove_hcd) from [<c05dc5a0>] (store_ehci_power+0x84/0x18c) r6:00000002 r5:c161d410 r4:c2c44c00 [<c05dc51c>] (store_ehci_power) from [<c04bc338>] (dev_attr_store+0x1c/0x28) r8:c33c1710 r7:c3355f00 r6:c33c1700 r5:c3d0d4c0 r4:c05dc51c [<c04bc31c>] (dev_attr_store) from [<c02cfd48>] (sysfs_kf_write+0x40/0x4c) r5:c3d0d4c0 r4:c04bc31c [<c02cfd08>] (sysfs_kf_write) from [<c02cedd0>] (kernfs_fop_write_iter+0xec/0x1ac) r5:c3d0d4c0 r4:00000002 [<c02cece4>] (kernfs_fop_write_iter) from [<c0253e74>] (vfs_write+0x1a8/0x204) r8:beb948d8 r7:00000000 r6:c3355f58 r5:c367b600 r4:00000002 [<c0253ccc>] (vfs_write) from [<c0254030>] (ksys_write+0x7c/0xd0) r8:00000002 r7:c3355f64 r6:c3355f58 r5:beb948d8 r4:c367b600 [<c0253fb4>] (ksys_write) from [<c0254094>] (sys_write+0x10/0x14) r8:c0100264 r7:00000004 r6:00000000 r5:beb948d8 r4:00000004 [<c0254084>] (sys_write) from [<c0100244>] (__sys_trace_return+0x0/0x1c) Exception stack(0xc3355fa8 to 0xc3355ff0) 5fa0: 00000004 beb948d8 00000004 beb948d8 00000002 00000000 5fc0: 00000004 beb948d8 00000000 00000004 b6f40550 b6c32328 00452960 00464000 5fe0: b6eed0ac beb948c0 b6ecc028 b6f01100 ---[ end trace 9e1c4c0c71f8dda6 ]--- Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
-rw-r--r--drivers/net/usb/sipc_hsic.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/usb/sipc_hsic.c b/drivers/net/usb/sipc_hsic.c
index 1809480cd5dd..e32acb07f1c0 100644
--- a/drivers/net/usb/sipc_hsic.c
+++ b/drivers/net/usb/sipc_hsic.c
@@ -32,6 +32,9 @@ struct sipc_usb_ep {
struct sipc_link_callback *cb;
struct usb_device *udev;
struct usb_interface *data_intf;
+
+ spinlock_t rx_lock; /* Protects disconnects */
+ bool disconnected;
};
#define linkops_to_ep(ops) container_of(ops, struct sipc_usb_ep, link_ops)
@@ -73,8 +76,16 @@ static void sipc_rx_complete(struct urb *urb)
static int sipc_start_rx(struct sipc_usb_ep *ep)
{
struct urb *urb;
+ unsigned long flags;
int ret;
+ spin_lock_irqsave(&ep->rx_lock, flags);
+
+ if (ep->disconnected) {
+ spin_unlock_irqrestore(&ep->rx_lock, flags);
+ return -ENODEV;
+ }
+
urb = ep->in_urb;
urb->transfer_flags = 0;
usb_fill_bulk_urb(urb, ep->udev,
@@ -83,6 +94,8 @@ static int sipc_start_rx(struct sipc_usb_ep *ep)
ep);
ret = usb_submit_urb(urb, GFP_ATOMIC);
+ spin_unlock_irqrestore(&ep->rx_lock, flags);
+
if (ret)
dev_err(&ep->udev->dev, "Failed to submit rx urb: %d\n", ret);
@@ -259,6 +272,8 @@ static int sipc_probe(struct usb_interface *intf,
}
}
+ spin_lock_init(&ep->rx_lock);
+
sipc_start_rx(ep);
return 0;
@@ -273,6 +288,8 @@ static void sipc_disconnect(struct usb_interface *intf)
struct sipc_usb_ep *ep = usb_get_intfdata(intf);
int fmt;
+ ep->disconnected = true;
+
fmt = usb_to_sipc_format(ep->ep);
if (fmt < 0)
goto invalid_format;