Re: [syzbot] KASAN: use-after-free Write in gadgetfs_kill_sb

From: Alan Stern
Date: Tue Dec 13 2022 - 11:05:33 EST


On Tue, Dec 13, 2022 at 05:36:38AM -0800, syzbot wrote:
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit: 830b3c68c1fb Linux 6.1
> git tree: upstream
> console+strace: https://syzkaller.appspot.com/x/log.txt?x=137401b7880000
> kernel config: https://syzkaller.appspot.com/x/.config?x=5a194ed4fc682723
> dashboard link: https://syzkaller.appspot.com/bug?extid=33d7ad66d65044b93f16
> compiler: Debian clang version 13.0.1-++20220126092033+75e33f71c2da-1~exp1~20220126212112.63, GNU ld (GNU Binutils for Debian) 2.35.2
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=176d36b7880000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=109371b7880000
>
> Downloadable assets:
> disk image: https://storage.googleapis.com/syzbot-assets/955d55d85d6c/disk-830b3c68.raw.xz
> vmlinux: https://storage.googleapis.com/syzbot-assets/7ef0e1f6a0c3/vmlinux-830b3c68.xz
> kernel image: https://storage.googleapis.com/syzbot-assets/27601eb5ff0b/bzImage-830b3c68.xz
>
> IMPORTANT: if you fix the issue, please add the following tag to the commit:
> Reported-by: syzbot+33d7ad66d65044b93f16@xxxxxxxxxxxxxxxxxxxxxxxxx
>
> ==================================================================
> BUG: KASAN: use-after-free in instrument_atomic_read_write include/linux/instrumented.h:102 [inline]
> BUG: KASAN: use-after-free in atomic_fetch_sub_release include/linux/atomic/atomic-instrumented.h:176 [inline]
> BUG: KASAN: use-after-free in __refcount_sub_and_test include/linux/refcount.h:272 [inline]
> BUG: KASAN: use-after-free in __refcount_dec_and_test include/linux/refcount.h:315 [inline]
> BUG: KASAN: use-after-free in refcount_dec_and_test include/linux/refcount.h:333 [inline]
> BUG: KASAN: use-after-free in put_dev drivers/usb/gadget/legacy/inode.c:159 [inline]
> BUG: KASAN: use-after-free in gadgetfs_kill_sb+0x33/0x100 drivers/usb/gadget/legacy/inode.c:2086
> Write of size 4 at addr ffff8880276d7840 by task syz-executor126/18689

#syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ 830b3c68c1fb

drivers/usb/gadget/legacy/inode.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)

Index: usb-devel/drivers/usb/gadget/legacy/inode.c
===================================================================
--- usb-devel.orig/drivers/usb/gadget/legacy/inode.c
+++ usb-devel/drivers/usb/gadget/legacy/inode.c
@@ -229,6 +229,7 @@ static void put_ep (struct ep_data *data
*/

static const char *CHIP;
+static DEFINE_MUTEX(sb_mutex); /* Serialize superblock operations */

/*----------------------------------------------------------------------*/

@@ -2010,13 +2011,20 @@ gadgetfs_fill_super (struct super_block
{
struct inode *inode;
struct dev_data *dev;
+ int rc;

- if (the_device)
- return -ESRCH;
+ mutex_lock(&sb_mutex);
+
+ if (the_device) {
+ rc = -ESRCH;
+ goto Done;
+ }

CHIP = usb_get_gadget_udc_name();
- if (!CHIP)
- return -ENODEV;
+ if (!CHIP) {
+ rc = -ENODEV;
+ goto Done;
+ }

/* superblock */
sb->s_blocksize = PAGE_SIZE;
@@ -2053,13 +2061,17 @@ gadgetfs_fill_super (struct super_block
* from binding to a controller.
*/
the_device = dev;
- return 0;
+ rc = 0;
+ goto Done;

-Enomem:
+ Enomem:
kfree(CHIP);
CHIP = NULL;
+ rc = -ENOMEM;

- return -ENOMEM;
+ Done:
+ mutex_unlock(&sb_mutex);
+ return rc;
}

/* "mount -t gadgetfs path /dev/gadget" ends up here */
@@ -2081,6 +2093,7 @@ static int gadgetfs_init_fs_context(stru
static void
gadgetfs_kill_sb (struct super_block *sb)
{
+ mutex_lock(&sb_mutex);
kill_litter_super (sb);
if (the_device) {
put_dev (the_device);
@@ -2088,6 +2101,7 @@ gadgetfs_kill_sb (struct super_block *sb
}
kfree(CHIP);
CHIP = NULL;
+ mutex_unlock(&sb_mutex);
}

/*----------------------------------------------------------------------*/