We report a bug (in linux-5.7) found by FuzzUSB (a modified version
of syzkaller)
The bug happened when accessing a deallocated instance of gs_port.
While spinning a lock in gs_flush_chars(),
port is allowed to be freed in gser_free_inst().
This ends up tringgering an memory error.
To fix this, it needs to check if port is is still in use, in particular,
lock spinning, when deallocating it.
==================================================================
BUG: KASAN: use-after-free in __lock_acquire+0x44f1/0x4aa0
kernel/locking/lockdep.c:4225
Read of size 8 at addr ffff88803bf5d398 by task syz-executor.7/3903
CPU: 3 PID: 3903 Comm: syz-executor.7 Not tainted 5.7.0 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0xce/0x128 lib/dump_stack.c:118
print_address_description.constprop.6+0x1f/0x410 mm/kasan/report.c:382
__kasan_report+0x106/0x140 mm/kasan/report.c:511
kasan_report+0x38/0x50 mm/kasan/common.c:625
__asan_report_load8_noabort+0x14/0x20 mm/kasan/generic_report.c:146
__lock_acquire+0x44f1/0x4aa0 kernel/locking/lockdep.c:4225
lock_acquire+0x18d/0xbe0 kernel/locking/lockdep.c:4934
__raw_spin_lock_irqsave ./include/linux/spinlock_api_smp.h:110 [inline]
_raw_spin_lock_irqsave+0x35/0x50 kernel/locking/spinlock.c:159
gs_flush_chars+0x45/0xb0 drivers/usb/gadget/function/u_serial.c:764
n_tty_write+0x685/0xe70 drivers/tty/n_tty.c:2350
do_tty_write drivers/tty/tty_io.c:962 [inline]
tty_write+0x462/0x970 drivers/tty/tty_io.c:1046
__vfs_write+0x85/0x110 fs/read_write.c:495
vfs_write+0x1d3/0x520 fs/read_write.c:559
ksys_write+0x190/0x220 fs/read_write.c:612
__do_sys_write fs/read_write.c:624 [inline]
__se_sys_write fs/read_write.c:621 [inline]
__x64_sys_write+0x73/0xb0 fs/read_write.c:621
do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:295
entry_SYSCALL_64_after_hwframe+0x49/0xb3
RIP: 0033:0x453769
Code: ed 60 fc ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48
89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d
01 f0 ff ff 0f 83 bb 60 fc ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f7f29106c78 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 000000000073bf00 RCX: 0000000000453769
RDX: 0000000000000000 RSI: 00000000200000c0 RDI: 0000000000000003
RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00000000004c0ed1
R13: 00000000004d8fa0 R14: 00007f7f291076d4 R15: 00000000ffffffff
Allocated by task 2445:
save_stack+0x21/0x50 mm/kasan/common.c:49
set_track mm/kasan/common.c:57 [inline]
__kasan_kmalloc.constprop.3+0xa7/0xd0 mm/kasan/common.c:495
kasan_kmalloc+0x9/0x10 mm/kasan/common.c:509
kmem_cache_alloc_trace+0xfa/0x2d0 mm/slub.c:2824
kmalloc ./include/linux/slab.h:555 [inline]
kzalloc ./include/linux/slab.h:669 [inline]
gs_port_alloc drivers/usb/gadget/function/u_serial.c:1142 [inline]
gserial_alloc_line_no_console+0xdc/0x920
drivers/usb/gadget/function/u_serial.c:1222
gserial_alloc_line+0x17/0x70 drivers/usb/gadget/function/u_serial.c:1256
gser_alloc_inst+0x8d/0xf0 drivers/usb/gadget/function/f_serial.c:327
try_get_usb_function_instance+0xf8/0x1c0 drivers/usb/gadget/functions.c:28
usb_get_function_instance+0x17/0x80 drivers/usb/gadget/functions.c:44
function_make+0xfa/0x3c0 drivers/usb/gadget/configfs.c:600
configfs_mkdir+0x458/0xaf0 fs/configfs/dir.c:1344
vfs_mkdir+0x3aa/0x670 fs/namei.c:3625
do_mkdirat+0x12b/0x220 fs/namei.c:3648
__do_sys_mkdir fs/namei.c:3664 [inline]
__se_sys_mkdir fs/namei.c:3662 [inline]
__x64_sys_mkdir+0x5c/0x80 fs/namei.c:3662
do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:295
entry_SYSCALL_64_after_hwframe+0x49/0xb3
Freed by task 3905:
save_stack+0x21/0x50 mm/kasan/common.c:49
set_track mm/kasan/common.c:57 [inline]
kasan_set_free_info mm/kasan/common.c:317 [inline]
__kasan_slab_free+0x135/0x190 mm/kasan/common.c:456
kasan_slab_free+0xe/0x10 mm/kasan/common.c:465
slab_free_hook mm/slub.c:1455 [inline]
slab_free_freelist_hook mm/slub.c:1488 [inline]
slab_free mm/slub.c:3045 [inline]
kfree+0xf7/0x410 mm/slub.c:4026
gserial_free_port+0x124/0x250 drivers/usb/gadget/function/u_serial.c:1186
gserial_free_line+0x12b/0x270 drivers/usb/gadget/function/u_serial.c:1203
gser_free_inst+0x3d/0x50 drivers/usb/gadget/function/f_serial.c:313
usb_put_function_instance+0x86/0xb0 drivers/usb/gadget/functions.c:77
serial_attr_release+0x15/0x20 drivers/usb/gadget/function/f_serial.c:262
config_item_cleanup fs/configfs/item.c:130 [inline]
config_item_release fs/configfs/item.c:139 [inline]
kref_put ./include/linux/kref.h:65 [inline]
config_item_put.part.0+0x191/0x250 fs/configfs/item.c:151
config_item_put+0x1f/0x30 fs/configfs/item.c:150
configfs_rmdir+0x58e/0x870 fs/configfs/dir.c:1555
vfs_rmdir+0x168/0x490 fs/namei.c:3688
do_rmdir+0x2f2/0x3a0 fs/namei.c:3750
__do_sys_rmdir fs/namei.c:3768 [inline]
__se_sys_rmdir fs/namei.c:3766 [inline]
__x64_sys_rmdir+0x36/0x40 fs/namei.c:3766
do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:295
entry_SYSCALL_64_after_hwframe+0x49/0xb3
The buggy address belongs to the object at ffff88803bf5d000
which belongs to the cache kmalloc-2k of size 2048
The buggy address is located 920 bytes inside of
2048-byte region [ffff88803bf5d000, ffff88803bf5d800)
The buggy address belongs to the page:
page:ffffea0000efd600 refcount:1 mapcount:0 mapping:0000000000000000
index:0x0 head:ffffea0000efd600 order:3 compound_mapcount:0
compound_pincount:0
flags: 0x100000000010200(slab|head)
raw: 0100000000010200 0000000000000000 0000000100000001 ffff88806c00e080
raw: 0000000000000000 0000000000080008 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88803bf5d280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88803bf5d300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff88803bf5d380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff88803bf5d400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88803bf5d480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================