[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <4667816e-a093-4993-8d0d-332bde366f7d@suse.com>
Date: Thu, 29 Sep 2022 13:41:03 +0200
From: Oliver Neukum <oneukum@...e.com>
To: Rondreis <linhaoguo86@...il.com>, linux-kernel@...r.kernel.org,
linux-usb@...r.kernel.org, johan@...nel.org,
Greg KH <gregkh@...uxfoundation.org>
Subject: Re: KASAN: use-after-free Write in keyspan_close
On 20.09.22 16:47, Rondreis wrote:
> Hello,
>
> When fuzzing the Linux kernel driver v6.0-rc6, the following crash was
> triggered.
>
> HEAD commit: 521a547ced6477c54b4b0cc206000406c221b4d6
> git tree: upstream
>
> kernel config: https://pastebin.com/raw/hekxU61F
> console output: https://pastebin.com/raw/gvADdA0t
>
> Sorry for failing to extract the reproducer. But on other versions of
> Linux, I also triggered this crash.
>
> I would appreciate it if you have any idea how to solve this bug.
>
> The crash report is as follows:
> ==================================================================
> BUG: KASAN: use-after-free in keyspan_close+0x240/0x260
> kasan_report+0x8a/0x1b0 mm/kasan/report.c:495
> keyspan_close+0x240/0x260 drivers/usb/serial/keyspan.c:1589
> serial_port_shutdown+0x89/0x110 drivers/usb/serial/usb-serial.c:309
> tty_port_shutdown+0x1ec/0x270 drivers/tty/tty_port.c:379
> tty_port_hangup+0x103/0x170 drivers/tty/tty_port.c:407
> __tty_hangup.part.0+0x65b/0x770 drivers/tty/tty_io.c:660
> __tty_hangup drivers/tty/tty_io.c:592 [inline]
> tty_vhangup drivers/tty/tty_io.c:707 [inline]
> tty_ioctl+0x956/0x1430 drivers/tty/tty_io.c:2718
This is triggered regularly by the reproducer:
r0 = openat$ttynull(0xffffffffffffff9c,
&(0x7f00000000c0)='/dev/ttyUSB1', 0x0, 0x0)
[..]
ioctl$TIOCVHANGUP(r0, 0x5437, 0x0)
basically just the ioctl()
> Freed by task 9889:
> usb_serial_device_remove+0x13f/0x1a0 drivers/usb/serial/bus.c:97
> device_remove+0xc8/0x170 drivers/base/dd.c:548
> __device_release_driver drivers/base/dd.c:1249 [inline]
> device_release_driver_internal+0x1a7/0x360 drivers/base/dd.c:1275
> bus_remove_device+0x2e3/0x590 drivers/base/bus.c:529
> device_del+0x5d2/0xe80 drivers/base/core.c:3704
> usb_serial_disconnect+0x23e/0x3b0 drivers/usb/serial/usb-serial.c:1205
> usb_unbind_interface+0x1bd/0x890 drivers/usb/core/driver.c:458
> device_remove drivers/base/dd.c:550 [inline]
Regular disconnect
Looking at keyspan_close():
static void keyspan_close(struct usb_serial_port *port)
{
int i;
struct keyspan_port_private *p_priv;
p_priv = usb_get_serial_port_data(port);
p_priv->rts_state = 0;
p_priv->dtr_state = 0;
keyspan_send_setup(port, 2);
It is clearly written so that it must never run after
usb_serial_disconnect(). I must say that I do not clearly
understand how this is achieved.
For testing purposes could you add a check for !serial->disconnected
to the call of close() in serial_port_shutdown()?
Regards
Oliver
Powered by blists - more mailing lists