From: Alan Stern <stern@rowland.harvard.edu>
To: syzbot <syzbot+200d4bb11b23d929335f@syzkaller.appspotmail.com>
Cc: andreyknvl@google.com, <chunkeey@gmail.com>,
<chunkeey@googlemail.com>, <davem@davemloft.net>,
<kvalo@codeaurora.org>, <linux-kernel@vger.kernel.org>,
<linux-usb@vger.kernel.org>, <linux-wireless@vger.kernel.org>,
<netdev@vger.kernel.org>, <oneukum@suse.com>,
<syzkaller-bugs@googlegroups.com>
Subject: Re: KASAN: use-after-free Read in p54u_load_firmware_cb
Date: Sat, 18 May 2019 12:32:09 -0400 (EDT) [thread overview]
Message-ID: <Pine.LNX.4.44L0.1905181202500.7855-100000@netrider.rowland.org> (raw)
In-Reply-To: <000000000000add98105892b73ec@google.com>
On Sat, 18 May 2019, syzbot wrote:
> Hello,
>
> syzbot has tested the proposed patch but the reproducer still triggered
> crash:
> KASAN: slab-out-of-bounds Read in p54u_load_firmware_cb
>
> usb 6-1: Direct firmware load for isl3887usb failed with error -2
> p54u_load_firmware_cb: priv->udev = ffff88809ad5bb80
> usb 6-1: Firmware not found.
> ==================================================================
> BUG: KASAN: slab-out-of-bounds in p54u_load_firmware_cb+0x3c9/0x45f
> drivers/net/wireless/intersil/p54/p54usb.c:937
> Read of size 8 at addr ffff88809abab588 by task kworker/1:8/5526
If you look at the full console log, you'll see that this address is
different from all the addresses printed out earlier. Not what you
would expect.
Which makes me wonder: Suppose a disconnect occurs before the firmware
loader callback runs? p54_disconnect() will get stuck waiting for the
priv->fw_load_wait completion to fire. But when the callback runs, the
first thing it does is activate the completion.
So now p54_disconnect() can finish doing its thing, including
deallocating all the private data structures. Then when
p54u_load_firmware_cb() tries to read the contents of priv, it ends up
accessing deallocated memory!
The patch below tries to do things the right way.
Alan Stern
#syz test: https://github.com/google/kasan.git usb-fuzzer
drivers/net/wireless/intersil/p54/p54usb.c | 37 +++++++++++------------------
1 file changed, 15 insertions(+), 22 deletions(-)
Index: usb-devel/drivers/net/wireless/intersil/p54/p54usb.c
===================================================================
--- usb-devel.orig/drivers/net/wireless/intersil/p54/p54usb.c
+++ usb-devel/drivers/net/wireless/intersil/p54/p54usb.c
@@ -33,6 +33,8 @@ MODULE_ALIAS("prism54usb");
MODULE_FIRMWARE("isl3886usb");
MODULE_FIRMWARE("isl3887usb");
+static struct usb_driver p54u_driver;
+
/*
* Note:
*
@@ -921,9 +923,9 @@ static void p54u_load_firmware_cb(const
{
struct p54u_priv *priv = context;
struct usb_device *udev = priv->udev;
+ struct usb_interface *intf = priv->intf;
int err;
- complete(&priv->fw_wait_load);
if (firmware) {
priv->fw = firmware;
err = p54u_start_ops(priv);
@@ -932,23 +934,19 @@ static void p54u_load_firmware_cb(const
dev_err(&udev->dev, "Firmware not found.\n");
}
- if (err) {
- struct device *parent = priv->udev->dev.parent;
-
- dev_err(&udev->dev, "failed to initialize device (%d)\n", err);
-
- if (parent)
- device_lock(parent);
+ complete(&priv->fw_wait_load);
+ /*
+ * At this point p54u_disconnect may have already freed
+ * the "priv" context. Do not use it anymore!
+ */
+ priv = NULL;
- device_release_driver(&udev->dev);
- /*
- * At this point p54u_disconnect has already freed
- * the "priv" context. Do not use it anymore!
- */
- priv = NULL;
+ if (err) {
+ dev_err(&intf->dev, "failed to initialize device (%d)\n", err);
- if (parent)
- device_unlock(parent);
+ usb_lock_device(udev);
+ usb_driver_release_interface(intf, &p54u_driver);
+ usb_unlock_device(udev);
}
usb_put_dev(udev);
@@ -1011,8 +1009,6 @@ static int p54u_probe(struct usb_interfa
skb_queue_head_init(&priv->rx_queue);
init_usb_anchor(&priv->submitted);
- usb_get_dev(udev);
-
/* really lazy and simple way of figuring out if we're a 3887 */
/* TODO: should just stick the identification in the device table */
i = intf->altsetting->desc.bNumEndpoints;
@@ -1053,10 +1049,8 @@ static int p54u_probe(struct usb_interfa
priv->upload_fw = p54u_upload_firmware_net2280;
}
err = p54u_load_firmware(dev, intf);
- if (err) {
- usb_put_dev(udev);
+ if (err)
p54_free_common(dev);
- }
return err;
}
@@ -1072,7 +1066,6 @@ static void p54u_disconnect(struct usb_i
wait_for_completion(&priv->fw_wait_load);
p54_unregister_common(dev);
- usb_put_dev(interface_to_usbdev(intf));
release_firmware(priv->fw);
p54_free_common(dev);
}
next prev parent reply other threads:[~2019-05-18 16:32 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-06 11:16 KASAN: use-after-free Read in p54u_load_firmware_cb syzbot
2019-05-13 10:23 ` syzbot
2019-05-13 13:28 ` Oliver Neukum
2019-05-17 19:21 ` Christian Lamparter
2019-05-17 20:46 ` Alan Stern
2019-05-17 21:01 ` syzbot
2019-05-18 15:13 ` Alan Stern
2019-05-18 15:50 ` syzbot
2019-05-18 16:32 ` Alan Stern [this message]
2019-05-18 16:50 ` syzbot
2019-05-18 17:01 ` Alan Stern
2019-05-18 17:36 ` syzbot
2019-05-18 17:49 ` Alan Stern
2019-05-18 18:31 ` syzbot
2019-05-18 20:11 ` Christian Lamparter
2019-05-20 14:44 ` [PATCH] network: wireless: p54u: Fix race between disconnect and firmware loading Alan Stern
2019-05-24 21:19 ` Christian Lamparter
2019-05-28 12:11 ` Kalle Valo
2019-05-28 14:17 ` Alan Stern
2019-05-28 14:29 ` Kalle Valo
2019-06-25 4:43 ` [PATCH] p54usb: " Kalle Valo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.44L0.1905181202500.7855-100000@netrider.rowland.org \
--to=stern@rowland.harvard.edu \
--cc=andreyknvl@google.com \
--cc=chunkeey@gmail.com \
--cc=chunkeey@googlemail.com \
--cc=davem@davemloft.net \
--cc=kvalo@codeaurora.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=oneukum@suse.com \
--cc=syzbot+200d4bb11b23d929335f@syzkaller.appspotmail.com \
--cc=syzkaller-bugs@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).