diff mbox series

[BUG] KASAN: slab-use-after-free in slip_open

Message ID 5ae45813.3235.194db3d35f5.Coremail.stitch@zju.edu.cn (mailing list archive)
State RFC
Headers show
Series [BUG] KASAN: slab-use-after-free in slip_open | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Jiacheng Xu Feb. 6, 2025, 12:30 p.m. UTC
Hi developers:

We are reporting a Linux issue using a modified version of Syzkaller.

HEAD commit: 4bbf9020 6.13.0-rc4
git tree: upstream
kernel config: https://github.com/google/syzkaller/blob/master/dashboard/config/linux/upstream-apparmor-kasan.config
syz repro: https://drive.google.com/file/d/1XV9WHwMvK4eZIPuyjiWoTpyQ0FpDaUpT/view?usp=sharing
C reproducer: As this is a race condition, a stable C reproducer is not available yet.

Environment:
Ubuntu 22.04 on Linux 5.15
QEMU emulator version 6.2.0
qemu-system-x86_64 \
-m 2G \
-smp 2 \
-kernel /home/wd/bzImage \
-append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
-drive file=/home/wd/bullseye.img,format=raw \
-net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
-net nic,model=e1000 \
-enable-kvm \
-nographic \
-pidfile vm.pid \
2>&1 | tee vm.log

Steps to reproduce:
1. Setup a vm on given kernel.
2. Execute the syz reproducer with `./syz-execprog -executor=./syz-executor -repeat=20000 -procs=8 -cover=0 ~/repro.prog`

Description:
The SLIP driver suffers from a Use-After-Free issue in sl_sync() due to unsynchronized access to net_device pointers stored in slip_devs[]. When a device is being freed (for example, via tty_release()/netdev_run_todo()), sl_sync() may access it after it has been freed.

Patch:
We try to write a patch for the crash. And after applying the patch, the crash can no longer be triggered with the PoC.

If you fix this issue, please add the following tag to the commit:
Reported-by: Jiacheng Xu <stitch@zju.edu.cn>, Dylan Wolff <wolffd@comp.nus.edu.sg>
==================================================================
BUG: KASAN: slab-use-after-free in sl_sync drivers/net/slip/slip.c:732 [inline]
BUG: KASAN: slab-use-after-free in slip_open+0x293/0x1330 drivers/net/slip/slip.c:806
Read of size 4 at addr ffff88805cfca0b0 by task syz-executor.2/46673


CPU: 0 UID: 0 PID: 46673 Comm: syz-executor.2 Not tainted 6.13.0-rc4 #2


Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014

Sched_ext: serialise (enabled+all), task: runnable_at=-30ms
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x229/0x350 lib/dump_stack.c:120
 print_address_description mm/kasan/report.c:378 [inline]
 print_report+0x164/0x530 mm/kasan/report.c:489
 kasan_report+0x147/0x180 mm/kasan/report.c:602
 sl_sync drivers/net/slip/slip.c:732 [inline]
 slip_open+0x293/0x1330 drivers/net/slip/slip.c:806
 tty_ldisc_open+0xbd/0x120 drivers/tty/tty_ldisc.c:432
 tty_set_ldisc+0x32b/0x5c0 drivers/tty/tty_ldisc.c:563
 tiocsetd+0x126/0x170 drivers/tty/tty_io.c:2439
 tty_ioctl+0xe5c/0x1090 drivers/tty/tty_io.c:2739
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:906 [inline]
 __se_sys_ioctl+0x266/0x350 fs/ioctl.c:892
 do_syscall_x64 arch/x86/entry/common.c:52 [inline]
 do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fed56a903ad
Code: c3 e8 a7 2b 00 00 0f 1f 80 00 00 00 00 f3 0f 1e fa 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fed578b20c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007fed56bcbf80 RCX: 00007fed56a903ad
RDX: 0000000020000080 RSI: 0000000000005423 RDI: 0000000000000003
RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007fed578b2640
R13: 000000000000000e R14: 00007fed56a4fc90 R15: 00007fed578aa000
 </TASK>


Allocated by task 46683:


 kasan_save_stack mm/kasan/common.c:47 [inline]

 kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
 poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
 __kasan_kmalloc+0x89/0xa0 mm/kasan/common.c:394
 kasan_kmalloc include/linux/kasan.h:260 [inline]
 __do_kmalloc_node mm/slub.c:4298 [inline]
 __kmalloc_node_noprof+0x28c/0x530 mm/slub.c:4304
 __kvmalloc_node_noprof+0x70/0x180 mm/util.c:650
 alloc_netdev_mqs+0xa7/0x1870 net/core/dev.c:11209
 sl_alloc drivers/net/slip/slip.c:756 [inline]
 slip_open+0x483/0x1330 drivers/net/slip/slip.c:817
 tty_ldisc_open+0xbd/0x120 drivers/tty/tty_ldisc.c:432
 tty_set_ldisc+0x32b/0x5c0 drivers/tty/tty_ldisc.c:563
 tiocsetd+0x126/0x170 drivers/tty/tty_io.c:2439
 tty_ioctl+0xe5c/0x1090 drivers/tty/tty_io.c:2739
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:906 [inline]
 __se_sys_ioctl+0x266/0x350 fs/ioctl.c:892
 do_syscall_x64 arch/x86/entry/common.c:52 [inline]
 do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
 entry_SYSCALL_64_after_hwframe+0x77/0x7f


Freed by task 46682:


 kasan_save_stack mm/kasan/common.c:47 [inline]

 kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
 kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:582
 poison_slab_object mm/kasan/common.c:247 [inline]
 __kasan_slab_free+0x5a/0x70 mm/kasan/common.c:264
 kasan_slab_free include/linux/kasan.h:233 [inline]
 slab_free_hook mm/slub.c:2353 [inline]
 slab_free mm/slub.c:4613 [inline]
 kfree+0x196/0x450 mm/slub.c:4761
 device_release+0xcd/0x240
 kobject_cleanup lib/kobject.c:689 [inline]
 kobject_release lib/kobject.c:720 [inline]
 kref_put include/linux/kref.h:65 [inline]
 kobject_put+0x248/0x490 lib/kobject.c:737
 netdev_run_todo+0x10e0/0x1280 net/core/dev.c:10924
 tty_ldisc_kill+0xbf/0x150 drivers/tty/tty_ldisc.c:613
 tty_ldisc_release+0x1ae/0x210 drivers/tty/tty_ldisc.c:781
 tty_release_struct+0x2a/0x100 drivers/tty/tty_io.c:1690
 tty_release+0xe4d/0x1460 drivers/tty/tty_io.c:1861
 __fput+0x2ba/0xa80 fs/file_table.c:450
 __fput_sync+0x180/0x1e0 fs/file_table.c:535
 __do_sys_close fs/open.c:1554 [inline]
 __se_sys_close fs/open.c:1539 [inline]
 __x64_sys_close+0x93/0x120 fs/open.c:1539
 do_syscall_x64 arch/x86/entry/common.c:52 [inline]
 do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
 entry_SYSCALL_64_after_hwframe+0x77/0x7f


The buggy address belongs to the object at ffff88805cfca000


 which belongs to the cache kmalloc-cg-4k of size 4096

The buggy address is located 176 bytes inside of
 freed 4096-byte region [ffff88805cfca000, ffff88805cfcb000)


The buggy address belongs to the physical page:


page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5cfc8

head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
memcg:ffff888075c64a01
flags: 0x4fff00000000040(head|node=1|zone=1|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 04fff00000000040 ffff88801d44f500 dead000000000100 dead000000000122
raw: 0000000000000000 0000000000040004 00000001f5000000 ffff888075c64a01
head: 04fff00000000040 ffff88801d44f500 dead000000000100 dead000000000122
head: 0000000000000000 0000000000040004 00000001f5000000 ffff888075c64a01
head: 04fff00000000003 ffffea000173f201 ffffffffffffffff 0000000000000000
head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9660, tgid 9660 (syz-executor.1), ts 93383578089, free_ts 93076565836
 set_page_owner include/linux/page_owner.h:32 [inline]
 post_alloc_hook+0x1f6/0x240 mm/page_alloc.c:1558
 prep_new_page mm/page_alloc.c:1566 [inline]
 get_page_from_freelist+0x3586/0x36d0 mm/page_alloc.c:3476
 __alloc_pages_noprof+0x260/0x680 mm/page_alloc.c:4753
 alloc_pages_mpol_noprof+0x3c8/0x650 mm/mempolicy.c:2269
 alloc_slab_page+0x6a/0x110 mm/slub.c:2423
 allocate_slab+0x5f/0x2b0 mm/slub.c:2589
 new_slab mm/slub.c:2642 [inline]
 ___slab_alloc+0xbdf/0x1490 mm/slub.c:3830
 __slab_alloc mm/slub.c:3920 [inline]
 __slab_alloc_node mm/slub.c:3995 [inline]
 slab_alloc_node mm/slub.c:4156 [inline]
 __do_kmalloc_node mm/slub.c:4297 [inline]
 __kmalloc_node_track_caller_noprof+0x30f/0x520 mm/slub.c:4317
 kmemdup_noprof+0x2b/0x60 mm/util.c:135
 __addrconf_sysctl_register+0xb1/0x430 net/ipv6/addrconf.c:7221
 addrconf_sysctl_register+0x1bd/0x220 net/ipv6/addrconf.c:7287
 ipv6_add_dev+0xe13/0x13e0 net/ipv6/addrconf.c:456
 addrconf_notify+0x6d8/0x1170 net/ipv6/addrconf.c:3674
 notifier_call_chain+0x1c6/0x410 kernel/notifier.c:85
 call_netdevice_notifiers_extack net/core/dev.c:2034 [inline]
 call_netdevice_notifiers+0xd3/0x110 net/core/dev.c:2048
 register_netdevice+0x190c/0x1da0 net/core/dev.c:10632
page last free pid 100 tgid 100 stack trace:
 reset_page_owner include/linux/page_owner.h:25 [inline]
 free_pages_prepare mm/page_alloc.c:1127 [inline]
 free_unref_folios+0xe03/0x1860 mm/page_alloc.c:2706
 shrink_folio_list+0x4698/0x5c80 mm/vmscan.c:1483
 evict_folios+0x3b12/0x5610 mm/vmscan.c:4593
 try_to_shrink_lruvec+0x941/0xc10 mm/vmscan.c:4789
 shrink_one+0x20e/0x870 mm/vmscan.c:4834
 shrink_many mm/vmscan.c:4897 [inline]
 lru_gen_shrink_node mm/vmscan.c:4975 [inline]
 shrink_node+0x3862/0x3f20 mm/vmscan.c:5956
 kswapd_shrink_node mm/vmscan.c:6785 [inline]
 balance_pgdat mm/vmscan.c:6977 [inline]
 kswapd+0x1c9f/0x36f0 mm/vmscan.c:7246
 kthread+0x2c3/0x360 kernel/kthread.c:389
 ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244


Memory state around the buggy address:


 ffff88805cfc9f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc

 ffff88805cfca000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff88805cfca080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                     ^
 ffff88805cfca100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff88805cfca180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================

Hi developers:


We are reporting a Linux issue using a modified version of Syzkaller.


HEAD commit: 4bbf9020 6.13.0-rc4

git tree: upstream
kernel config: https://github.com/google/syzkaller/blob/master/dashboard/config/linux/upstream-apparmor-kasan.config
syz repro: https://drive.google.com/file/d/1XV9WHwMvK4eZIPuyjiWoTpyQ0FpDaUpT/view?usp=sharing
C reproducer: As this is a race condition, we cannot obtain a stable C reproducer.


Description:

The SLIP driver suffers from a concurrent Use-After-Free issue in sl_sync() due to
unsynchronized access to net_device pointers stored in slip_devs[]. When a
device is being freed (for example, via tty_release()/netdev_run_todo()),
sl_sync() may access it after it has been freed.

Steps to reproducer:

1. Setup a vm on the given kernel.
2. Use syzkaller to run syz repro with `./syz-execprog -executor=./syz-executor -repeat=20000 -procs=8 -cover=0 ~/repro.prog`.


Environment:

Ubuntu 22.04 on Linux 5.15
QEMU emulator version 6.2.0
qemu-system-x86_64 \
-m 2G \
-smp 2 \
-kernel /home/wd/bzImage \
-append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
-drive file=/home/wd/bullseye.img,format=raw \
-net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
-net nic,model=e1000 \
-enable-kvm \
-nographic \
-pidfile vm.pid \
2>&1 | tee vm.log

If you fix this issue, please add the following tag to the commit:

Reported-by: Jiacheng Xu <stitch@zju.edu.cn>

Comments

Eric Dumazet Feb. 6, 2025, 12:49 p.m. UTC | #1
On Thu, Feb 6, 2025 at 1:30 PM Jiacheng Xu <stitch@zju.edu.cn> wrote:
>
> Hi developers:
>
> We are reporting a Linux issue using a modified version of Syzkaller.
>
> HEAD commit: 4bbf9020 6.13.0-rc4
> git tree: upstream
> kernel config: https://github.com/google/syzkaller/blob/master/dashboard/config/linux/upstream-apparmor-kasan.config
> syz repro: https://drive.google.com/file/d/1XV9WHwMvK4eZIPuyjiWoTpyQ0FpDaUpT/view?usp=sharing
> C reproducer: As this is a race condition, a stable C reproducer is not available yet.
>
> Environment:
> Ubuntu 22.04 on Linux 5.15
> QEMU emulator version 6.2.0
> qemu-system-x86_64 \
> -m 2G \
> -smp 2 \
> -kernel /home/wd/bzImage \
> -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
> -drive file=/home/wd/bullseye.img,format=raw \
> -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
> -net nic,model=e1000 \
> -enable-kvm \
> -nographic \
> -pidfile vm.pid \
> 2>&1 | tee vm.log
>
> Steps to reproduce:
> 1. Setup a vm on given kernel.
> 2. Execute the syz reproducer with `./syz-execprog -executor=./syz-executor -repeat=20000 -procs=8 -cover=0 ~/repro.prog`
>
> Description:
> The SLIP driver suffers from a Use-After-Free issue in sl_sync() due to unsynchronized access to net_device pointers stored in slip_devs[]. When a device is being freed (for example, via tty_release()/netdev_run_todo()), sl_sync() may access it after it has been freed.
>
> Patch:
> We try to write a patch for the crash. And after applying the patch, the crash can no longer be triggered with the PoC.
>
> --- slip.c      2025-02-06 12:26:25.690890378 +0000
> +++ slip.c      2025-02-06 12:29:30.554820899 +0000
> @@ -721,8 +721,9 @@
>         struct net_device *dev;
>         struct slip       *sl;
>
> +       rcu_read_lock();
>         for (i = 0; i < slip_maxdev; i++) {
> -               dev = slip_devs[i];
> +               dev = rcu_dereference(slip_devs[i]);
>                 if (dev == NULL)
>                         break;
>
> @@ -732,6 +733,7 @@
>                 if (dev->flags & IFF_UP)
>                         dev_close(dev);
>         }
> +       rcu_read_unlock();
>  }
>

Hi there.

We had numerous public sybot reports with the same signature.

Your patch can not work, we can not call dev_close() under rcu_read_lock().




>
> If you fix this issue, please add the following tag to the commit:
> Reported-by: Jiacheng Xu <stitch@zju.edu.cn>, Dylan Wolff <wolffd@comp.nus.edu.sg>
> ==================================================================
> BUG: KASAN: slab-use-after-free in sl_sync drivers/net/slip/slip.c:732 [inline]
> BUG: KASAN: slab-use-after-free in slip_open+0x293/0x1330 drivers/net/slip/slip.c:806
> Read of size 4 at addr ffff88805cfca0b0 by task syz-executor.2/46673
>
>
> CPU: 0 UID: 0 PID: 46673 Comm: syz-executor.2 Not tainted 6.13.0-rc4 #2
>
>
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
>
> Sched_ext: serialise (enabled+all), task: runnable_at=-30ms
> Call Trace:
>  <TASK>
>  __dump_stack lib/dump_stack.c:94 [inline]
>  dump_stack_lvl+0x229/0x350 lib/dump_stack.c:120
>  print_address_description mm/kasan/report.c:378 [inline]
>  print_report+0x164/0x530 mm/kasan/report.c:489
>  kasan_report+0x147/0x180 mm/kasan/report.c:602
>  sl_sync drivers/net/slip/slip.c:732 [inline]
>  slip_open+0x293/0x1330 drivers/net/slip/slip.c:806
>  tty_ldisc_open+0xbd/0x120 drivers/tty/tty_ldisc.c:432
>  tty_set_ldisc+0x32b/0x5c0 drivers/tty/tty_ldisc.c:563
>  tiocsetd+0x126/0x170 drivers/tty/tty_io.c:2439
>  tty_ioctl+0xe5c/0x1090 drivers/tty/tty_io.c:2739
>  vfs_ioctl fs/ioctl.c:51 [inline]
>  __do_sys_ioctl fs/ioctl.c:906 [inline]
>  __se_sys_ioctl+0x266/0x350 fs/ioctl.c:892
>  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
>  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> RIP: 0033:0x7fed56a903ad
> Code: c3 e8 a7 2b 00 00 0f 1f 80 00 00 00 00 f3 0f 1e fa 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
> RSP: 002b:00007fed578b20c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
> RAX: ffffffffffffffda RBX: 00007fed56bcbf80 RCX: 00007fed56a903ad
> RDX: 0000000020000080 RSI: 0000000000005423 RDI: 0000000000000003
> RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000246 R12: 00007fed578b2640
> R13: 000000000000000e R14: 00007fed56a4fc90 R15: 00007fed578aa000
>  </TASK>
>
>
> Allocated by task 46683:
>
>
>  kasan_save_stack mm/kasan/common.c:47 [inline]
>
>  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
>  poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
>  __kasan_kmalloc+0x89/0xa0 mm/kasan/common.c:394
>  kasan_kmalloc include/linux/kasan.h:260 [inline]
>  __do_kmalloc_node mm/slub.c:4298 [inline]
>  __kmalloc_node_noprof+0x28c/0x530 mm/slub.c:4304
>  __kvmalloc_node_noprof+0x70/0x180 mm/util.c:650
>  alloc_netdev_mqs+0xa7/0x1870 net/core/dev.c:11209
>  sl_alloc drivers/net/slip/slip.c:756 [inline]
>  slip_open+0x483/0x1330 drivers/net/slip/slip.c:817
>  tty_ldisc_open+0xbd/0x120 drivers/tty/tty_ldisc.c:432
>  tty_set_ldisc+0x32b/0x5c0 drivers/tty/tty_ldisc.c:563
>  tiocsetd+0x126/0x170 drivers/tty/tty_io.c:2439
>  tty_ioctl+0xe5c/0x1090 drivers/tty/tty_io.c:2739
>  vfs_ioctl fs/ioctl.c:51 [inline]
>  __do_sys_ioctl fs/ioctl.c:906 [inline]
>  __se_sys_ioctl+0x266/0x350 fs/ioctl.c:892
>  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
>  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
>
> Freed by task 46682:
>
>
>  kasan_save_stack mm/kasan/common.c:47 [inline]
>
>  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
>  kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:582
>  poison_slab_object mm/kasan/common.c:247 [inline]
>  __kasan_slab_free+0x5a/0x70 mm/kasan/common.c:264
>  kasan_slab_free include/linux/kasan.h:233 [inline]
>  slab_free_hook mm/slub.c:2353 [inline]
>  slab_free mm/slub.c:4613 [inline]
>  kfree+0x196/0x450 mm/slub.c:4761
>  device_release+0xcd/0x240
>  kobject_cleanup lib/kobject.c:689 [inline]
>  kobject_release lib/kobject.c:720 [inline]
>  kref_put include/linux/kref.h:65 [inline]
>  kobject_put+0x248/0x490 lib/kobject.c:737
>  netdev_run_todo+0x10e0/0x1280 net/core/dev.c:10924
>  tty_ldisc_kill+0xbf/0x150 drivers/tty/tty_ldisc.c:613
>  tty_ldisc_release+0x1ae/0x210 drivers/tty/tty_ldisc.c:781
>  tty_release_struct+0x2a/0x100 drivers/tty/tty_io.c:1690
>  tty_release+0xe4d/0x1460 drivers/tty/tty_io.c:1861
>  __fput+0x2ba/0xa80 fs/file_table.c:450
>  __fput_sync+0x180/0x1e0 fs/file_table.c:535
>  __do_sys_close fs/open.c:1554 [inline]
>  __se_sys_close fs/open.c:1539 [inline]
>  __x64_sys_close+0x93/0x120 fs/open.c:1539
>  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
>  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
>
> The buggy address belongs to the object at ffff88805cfca000
>
>
>  which belongs to the cache kmalloc-cg-4k of size 4096
>
> The buggy address is located 176 bytes inside of
>  freed 4096-byte region [ffff88805cfca000, ffff88805cfcb000)
>
>
> The buggy address belongs to the physical page:
>
>
> page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5cfc8
>
> head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
> memcg:ffff888075c64a01
> flags: 0x4fff00000000040(head|node=1|zone=1|lastcpupid=0x7ff)
> page_type: f5(slab)
> raw: 04fff00000000040 ffff88801d44f500 dead000000000100 dead000000000122
> raw: 0000000000000000 0000000000040004 00000001f5000000 ffff888075c64a01
> head: 04fff00000000040 ffff88801d44f500 dead000000000100 dead000000000122
> head: 0000000000000000 0000000000040004 00000001f5000000 ffff888075c64a01
> head: 04fff00000000003 ffffea000173f201 ffffffffffffffff 0000000000000000
> head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
> page dumped because: kasan: bad access detected
> page_owner tracks the page as allocated
> page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9660, tgid 9660 (syz-executor.1), ts 93383578089, free_ts 93076565836
>  set_page_owner include/linux/page_owner.h:32 [inline]
>  post_alloc_hook+0x1f6/0x240 mm/page_alloc.c:1558
>  prep_new_page mm/page_alloc.c:1566 [inline]
>  get_page_from_freelist+0x3586/0x36d0 mm/page_alloc.c:3476
>  __alloc_pages_noprof+0x260/0x680 mm/page_alloc.c:4753
>  alloc_pages_mpol_noprof+0x3c8/0x650 mm/mempolicy.c:2269
>  alloc_slab_page+0x6a/0x110 mm/slub.c:2423
>  allocate_slab+0x5f/0x2b0 mm/slub.c:2589
>  new_slab mm/slub.c:2642 [inline]
>  ___slab_alloc+0xbdf/0x1490 mm/slub.c:3830
>  __slab_alloc mm/slub.c:3920 [inline]
>  __slab_alloc_node mm/slub.c:3995 [inline]
>  slab_alloc_node mm/slub.c:4156 [inline]
>  __do_kmalloc_node mm/slub.c:4297 [inline]
>  __kmalloc_node_track_caller_noprof+0x30f/0x520 mm/slub.c:4317
>  kmemdup_noprof+0x2b/0x60 mm/util.c:135
>  __addrconf_sysctl_register+0xb1/0x430 net/ipv6/addrconf.c:7221
>  addrconf_sysctl_register+0x1bd/0x220 net/ipv6/addrconf.c:7287
>  ipv6_add_dev+0xe13/0x13e0 net/ipv6/addrconf.c:456
>  addrconf_notify+0x6d8/0x1170 net/ipv6/addrconf.c:3674
>  notifier_call_chain+0x1c6/0x410 kernel/notifier.c:85
>  call_netdevice_notifiers_extack net/core/dev.c:2034 [inline]
>  call_netdevice_notifiers+0xd3/0x110 net/core/dev.c:2048
>  register_netdevice+0x190c/0x1da0 net/core/dev.c:10632
> page last free pid 100 tgid 100 stack trace:
>  reset_page_owner include/linux/page_owner.h:25 [inline]
>  free_pages_prepare mm/page_alloc.c:1127 [inline]
>  free_unref_folios+0xe03/0x1860 mm/page_alloc.c:2706
>  shrink_folio_list+0x4698/0x5c80 mm/vmscan.c:1483
>  evict_folios+0x3b12/0x5610 mm/vmscan.c:4593
>  try_to_shrink_lruvec+0x941/0xc10 mm/vmscan.c:4789
>  shrink_one+0x20e/0x870 mm/vmscan.c:4834
>  shrink_many mm/vmscan.c:4897 [inline]
>  lru_gen_shrink_node mm/vmscan.c:4975 [inline]
>  shrink_node+0x3862/0x3f20 mm/vmscan.c:5956
>  kswapd_shrink_node mm/vmscan.c:6785 [inline]
>  balance_pgdat mm/vmscan.c:6977 [inline]
>  kswapd+0x1c9f/0x36f0 mm/vmscan.c:7246
>  kthread+0x2c3/0x360 kernel/kthread.c:389
>  ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
>  ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
>
>
> Memory state around the buggy address:
>
>
>  ffff88805cfc9f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>
>  ffff88805cfca000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> >ffff88805cfca080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>                                      ^
>  ffff88805cfca100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>  ffff88805cfca180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ==================================================================
>
> Hi developers:
>
>
> We are reporting a Linux issue using a modified version of Syzkaller.
>
>
> HEAD commit: 4bbf9020 6.13.0-rc4
>
> git tree: upstream
> kernel config: https://github.com/google/syzkaller/blob/master/dashboard/config/linux/upstream-apparmor-kasan.config
> syz repro: https://drive.google.com/file/d/1XV9WHwMvK4eZIPuyjiWoTpyQ0FpDaUpT/view?usp=sharing
> C reproducer: As this is a race condition, we cannot obtain a stable C reproducer.
>
>
> Description:
>
> The SLIP driver suffers from a concurrent Use-After-Free issue in sl_sync() due to
> unsynchronized access to net_device pointers stored in slip_devs[]. When a
> device is being freed (for example, via tty_release()/netdev_run_todo()),
> sl_sync() may access it after it has been freed.
>
> Steps to reproducer:
>
> 1. Setup a vm on the given kernel.
> 2. Use syzkaller to run syz repro with `./syz-execprog -executor=./syz-executor -repeat=20000 -procs=8 -cover=0 ~/repro.prog`.
>
>
> Environment:
>
> Ubuntu 22.04 on Linux 5.15
> QEMU emulator version 6.2.0
> qemu-system-x86_64 \
> -m 2G \
> -smp 2 \
> -kernel /home/wd/bzImage \
> -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
> -drive file=/home/wd/bullseye.img,format=raw \
> -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
> -net nic,model=e1000 \
> -enable-kvm \
> -nographic \
> -pidfile vm.pid \
> 2>&1 | tee vm.log
>
> If you fix this issue, please add the following tag to the commit:
>
> Reported-by: Jiacheng Xu <stitch@zju.edu.cn>
>
Jiacheng Xu Feb. 6, 2025, 1:22 p.m. UTC | #2
Hi Eric,

We are a bit confused by your response. Could you please clarify whether you think this is simply a false positive report or if you are suggesting that the patch is ineffective?

While syzbot may have reported this issue previously and mark it as invalid, the key difference is that we can now reliably reproduce the crash using a syz repro. If your developers can confirm the issue, we would be happy to collaborate on developing a more effective patch.

Best regards,
Jiacheng

> -----原始邮件-----
> 发件人: "Eric Dumazet" <edumazet@google.com>
> 发送时间:2025-02-06 20:49:17 (星期四)
> 收件人: "Jiacheng Xu" <stitch@zju.edu.cn>
> 抄送: andrew+netdev@lunn.ch, davem@davemloft.net, kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, wolffd@comp.nus.edu.sg
> 主题: Re: [BUG] KASAN: slab-use-after-free in slip_open
> 
> On Thu, Feb 6, 2025 at 1:30 PM Jiacheng Xu <stitch@zju.edu.cn> wrote:
> >
> > Hi developers:
> >
> > We are reporting a Linux issue using a modified version of Syzkaller.
> >
> > HEAD commit: 4bbf9020 6.13.0-rc4
> > git tree: upstream
> > kernel config: https://github.com/google/syzkaller/blob/master/dashboard/config/linux/upstream-apparmor-kasan.config
> > syz repro: https://drive.google.com/file/d/1XV9WHwMvK4eZIPuyjiWoTpyQ0FpDaUpT/view?usp=sharing
> > C reproducer: As this is a race condition, a stable C reproducer is not available yet.
> >
> > Environment:
> > Ubuntu 22.04 on Linux 5.15
> > QEMU emulator version 6.2.0
> > qemu-system-x86_64 \
> > -m 2G \
> > -smp 2 \
> > -kernel /home/wd/bzImage \
> > -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
> > -drive file=/home/wd/bullseye.img,format=raw \
> > -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
> > -net nic,model=e1000 \
> > -enable-kvm \
> > -nographic \
> > -pidfile vm.pid \
> > 2>&1 | tee vm.log
> >
> > Steps to reproduce:
> > 1. Setup a vm on given kernel.
> > 2. Execute the syz reproducer with `./syz-execprog -executor=./syz-executor -repeat=20000 -procs=8 -cover=0 ~/repro.prog`
> >
> > Description:
> > The SLIP driver suffers from a Use-After-Free issue in sl_sync() due to unsynchronized access to net_device pointers stored in slip_devs[]. When a device is being freed (for example, via tty_release()/netdev_run_todo()), sl_sync() may access it after it has been freed.
> >
> > Patch:
> > We try to write a patch for the crash. And after applying the patch, the crash can no longer be triggered with the PoC.
> >
> > --- slip.c      2025-02-06 12:26:25.690890378 +0000
> > +++ slip.c      2025-02-06 12:29:30.554820899 +0000
> > @@ -721,8 +721,9 @@
> >         struct net_device *dev;
> >         struct slip       *sl;
> >
> > +       rcu_read_lock();
> >         for (i = 0; i < slip_maxdev; i++) {
> > -               dev = slip_devs[i];
> > +               dev = rcu_dereference(slip_devs[i]);
> >                 if (dev == NULL)
> >                         break;
> >
> > @@ -732,6 +733,7 @@
> >                 if (dev->flags & IFF_UP)
> >                         dev_close(dev);
> >         }
> > +       rcu_read_unlock();
> >  }
> >
> 
> Hi there.
> 
> We had numerous public sybot reports with the same signature.
> 
> Your patch can not work, we can not call dev_close() under rcu_read_lock().
> 
> 
> 
> 
> >
> > If you fix this issue, please add the following tag to the commit:
> > Reported-by: Jiacheng Xu <stitch@zju.edu.cn>, Dylan Wolff <wolffd@comp.nus.edu.sg>
> > ==================================================================
> > BUG: KASAN: slab-use-after-free in sl_sync drivers/net/slip/slip.c:732 [inline]
> > BUG: KASAN: slab-use-after-free in slip_open+0x293/0x1330 drivers/net/slip/slip.c:806
> > Read of size 4 at addr ffff88805cfca0b0 by task syz-executor.2/46673
> >
> >
> > CPU: 0 UID: 0 PID: 46673 Comm: syz-executor.2 Not tainted 6.13.0-rc4 #2
> >
> >
> > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
> >
> > Sched_ext: serialise (enabled+all), task: runnable_at=-30ms
> > Call Trace:
> >  <TASK>
> >  __dump_stack lib/dump_stack.c:94 [inline]
> >  dump_stack_lvl+0x229/0x350 lib/dump_stack.c:120
> >  print_address_description mm/kasan/report.c:378 [inline]
> >  print_report+0x164/0x530 mm/kasan/report.c:489
> >  kasan_report+0x147/0x180 mm/kasan/report.c:602
> >  sl_sync drivers/net/slip/slip.c:732 [inline]
> >  slip_open+0x293/0x1330 drivers/net/slip/slip.c:806
> >  tty_ldisc_open+0xbd/0x120 drivers/tty/tty_ldisc.c:432
> >  tty_set_ldisc+0x32b/0x5c0 drivers/tty/tty_ldisc.c:563
> >  tiocsetd+0x126/0x170 drivers/tty/tty_io.c:2439
> >  tty_ioctl+0xe5c/0x1090 drivers/tty/tty_io.c:2739
> >  vfs_ioctl fs/ioctl.c:51 [inline]
> >  __do_sys_ioctl fs/ioctl.c:906 [inline]
> >  __se_sys_ioctl+0x266/0x350 fs/ioctl.c:892
> >  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
> >  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
> >  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> > RIP: 0033:0x7fed56a903ad
> > Code: c3 e8 a7 2b 00 00 0f 1f 80 00 00 00 00 f3 0f 1e fa 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
> > RSP: 002b:00007fed578b20c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
> > RAX: ffffffffffffffda RBX: 00007fed56bcbf80 RCX: 00007fed56a903ad
> > RDX: 0000000020000080 RSI: 0000000000005423 RDI: 0000000000000003
> > RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
> > R10: 0000000000000000 R11: 0000000000000246 R12: 00007fed578b2640
> > R13: 000000000000000e R14: 00007fed56a4fc90 R15: 00007fed578aa000
> >  </TASK>
> >
> >
> > Allocated by task 46683:
> >
> >
> >  kasan_save_stack mm/kasan/common.c:47 [inline]
> >
> >  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
> >  poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
> >  __kasan_kmalloc+0x89/0xa0 mm/kasan/common.c:394
> >  kasan_kmalloc include/linux/kasan.h:260 [inline]
> >  __do_kmalloc_node mm/slub.c:4298 [inline]
> >  __kmalloc_node_noprof+0x28c/0x530 mm/slub.c:4304
> >  __kvmalloc_node_noprof+0x70/0x180 mm/util.c:650
> >  alloc_netdev_mqs+0xa7/0x1870 net/core/dev.c:11209
> >  sl_alloc drivers/net/slip/slip.c:756 [inline]
> >  slip_open+0x483/0x1330 drivers/net/slip/slip.c:817
> >  tty_ldisc_open+0xbd/0x120 drivers/tty/tty_ldisc.c:432
> >  tty_set_ldisc+0x32b/0x5c0 drivers/tty/tty_ldisc.c:563
> >  tiocsetd+0x126/0x170 drivers/tty/tty_io.c:2439
> >  tty_ioctl+0xe5c/0x1090 drivers/tty/tty_io.c:2739
> >  vfs_ioctl fs/ioctl.c:51 [inline]
> >  __do_sys_ioctl fs/ioctl.c:906 [inline]
> >  __se_sys_ioctl+0x266/0x350 fs/ioctl.c:892
> >  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
> >  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
> >  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> >
> >
> > Freed by task 46682:
> >
> >
> >  kasan_save_stack mm/kasan/common.c:47 [inline]
> >
> >  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
> >  kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:582
> >  poison_slab_object mm/kasan/common.c:247 [inline]
> >  __kasan_slab_free+0x5a/0x70 mm/kasan/common.c:264
> >  kasan_slab_free include/linux/kasan.h:233 [inline]
> >  slab_free_hook mm/slub.c:2353 [inline]
> >  slab_free mm/slub.c:4613 [inline]
> >  kfree+0x196/0x450 mm/slub.c:4761
> >  device_release+0xcd/0x240
> >  kobject_cleanup lib/kobject.c:689 [inline]
> >  kobject_release lib/kobject.c:720 [inline]
> >  kref_put include/linux/kref.h:65 [inline]
> >  kobject_put+0x248/0x490 lib/kobject.c:737
> >  netdev_run_todo+0x10e0/0x1280 net/core/dev.c:10924
> >  tty_ldisc_kill+0xbf/0x150 drivers/tty/tty_ldisc.c:613
> >  tty_ldisc_release+0x1ae/0x210 drivers/tty/tty_ldisc.c:781
> >  tty_release_struct+0x2a/0x100 drivers/tty/tty_io.c:1690
> >  tty_release+0xe4d/0x1460 drivers/tty/tty_io.c:1861
> >  __fput+0x2ba/0xa80 fs/file_table.c:450
> >  __fput_sync+0x180/0x1e0 fs/file_table.c:535
> >  __do_sys_close fs/open.c:1554 [inline]
> >  __se_sys_close fs/open.c:1539 [inline]
> >  __x64_sys_close+0x93/0x120 fs/open.c:1539
> >  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
> >  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
> >  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> >
> >
> > The buggy address belongs to the object at ffff88805cfca000
> >
> >
> >  which belongs to the cache kmalloc-cg-4k of size 4096
> >
> > The buggy address is located 176 bytes inside of
> >  freed 4096-byte region [ffff88805cfca000, ffff88805cfcb000)
> >
> >
> > The buggy address belongs to the physical page:
> >
> >
> > page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5cfc8
> >
> > head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
> > memcg:ffff888075c64a01
> > flags: 0x4fff00000000040(head|node=1|zone=1|lastcpupid=0x7ff)
> > page_type: f5(slab)
> > raw: 04fff00000000040 ffff88801d44f500 dead000000000100 dead000000000122
> > raw: 0000000000000000 0000000000040004 00000001f5000000 ffff888075c64a01
> > head: 04fff00000000040 ffff88801d44f500 dead000000000100 dead000000000122
> > head: 0000000000000000 0000000000040004 00000001f5000000 ffff888075c64a01
> > head: 04fff00000000003 ffffea000173f201 ffffffffffffffff 0000000000000000
> > head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
> > page dumped because: kasan: bad access detected
> > page_owner tracks the page as allocated
> > page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9660, tgid 9660 (syz-executor.1), ts 93383578089, free_ts 93076565836
> >  set_page_owner include/linux/page_owner.h:32 [inline]
> >  post_alloc_hook+0x1f6/0x240 mm/page_alloc.c:1558
> >  prep_new_page mm/page_alloc.c:1566 [inline]
> >  get_page_from_freelist+0x3586/0x36d0 mm/page_alloc.c:3476
> >  __alloc_pages_noprof+0x260/0x680 mm/page_alloc.c:4753
> >  alloc_pages_mpol_noprof+0x3c8/0x650 mm/mempolicy.c:2269
> >  alloc_slab_page+0x6a/0x110 mm/slub.c:2423
> >  allocate_slab+0x5f/0x2b0 mm/slub.c:2589
> >  new_slab mm/slub.c:2642 [inline]
> >  ___slab_alloc+0xbdf/0x1490 mm/slub.c:3830
> >  __slab_alloc mm/slub.c:3920 [inline]
> >  __slab_alloc_node mm/slub.c:3995 [inline]
> >  slab_alloc_node mm/slub.c:4156 [inline]
> >  __do_kmalloc_node mm/slub.c:4297 [inline]
> >  __kmalloc_node_track_caller_noprof+0x30f/0x520 mm/slub.c:4317
> >  kmemdup_noprof+0x2b/0x60 mm/util.c:135
> >  __addrconf_sysctl_register+0xb1/0x430 net/ipv6/addrconf.c:7221
> >  addrconf_sysctl_register+0x1bd/0x220 net/ipv6/addrconf.c:7287
> >  ipv6_add_dev+0xe13/0x13e0 net/ipv6/addrconf.c:456
> >  addrconf_notify+0x6d8/0x1170 net/ipv6/addrconf.c:3674
> >  notifier_call_chain+0x1c6/0x410 kernel/notifier.c:85
> >  call_netdevice_notifiers_extack net/core/dev.c:2034 [inline]
> >  call_netdevice_notifiers+0xd3/0x110 net/core/dev.c:2048
> >  register_netdevice+0x190c/0x1da0 net/core/dev.c:10632
> > page last free pid 100 tgid 100 stack trace:
> >  reset_page_owner include/linux/page_owner.h:25 [inline]
> >  free_pages_prepare mm/page_alloc.c:1127 [inline]
> >  free_unref_folios+0xe03/0x1860 mm/page_alloc.c:2706
> >  shrink_folio_list+0x4698/0x5c80 mm/vmscan.c:1483
> >  evict_folios+0x3b12/0x5610 mm/vmscan.c:4593
> >  try_to_shrink_lruvec+0x941/0xc10 mm/vmscan.c:4789
> >  shrink_one+0x20e/0x870 mm/vmscan.c:4834
> >  shrink_many mm/vmscan.c:4897 [inline]
> >  lru_gen_shrink_node mm/vmscan.c:4975 [inline]
> >  shrink_node+0x3862/0x3f20 mm/vmscan.c:5956
> >  kswapd_shrink_node mm/vmscan.c:6785 [inline]
> >  balance_pgdat mm/vmscan.c:6977 [inline]
> >  kswapd+0x1c9f/0x36f0 mm/vmscan.c:7246
> >  kthread+0x2c3/0x360 kernel/kthread.c:389
> >  ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
> >  ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
> >
> >
> > Memory state around the buggy address:
> >
> >
> >  ffff88805cfc9f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >
> >  ffff88805cfca000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> > >ffff88805cfca080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> >                                      ^
> >  ffff88805cfca100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> >  ffff88805cfca180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> > ==================================================================
> >
> > Hi developers:
> >
> >
> > We are reporting a Linux issue using a modified version of Syzkaller.
> >
> >
> > HEAD commit: 4bbf9020 6.13.0-rc4
> >
> > git tree: upstream
> > kernel config: https://github.com/google/syzkaller/blob/master/dashboard/config/linux/upstream-apparmor-kasan.config
> > syz repro: https://drive.google.com/file/d/1XV9WHwMvK4eZIPuyjiWoTpyQ0FpDaUpT/view?usp=sharing
> > C reproducer: As this is a race condition, we cannot obtain a stable C reproducer.
> >
> >
> > Description:
> >
> > The SLIP driver suffers from a concurrent Use-After-Free issue in sl_sync() due to
> > unsynchronized access to net_device pointers stored in slip_devs[]. When a
> > device is being freed (for example, via tty_release()/netdev_run_todo()),
> > sl_sync() may access it after it has been freed.
> >
> > Steps to reproducer:
> >
> > 1. Setup a vm on the given kernel.
> > 2. Use syzkaller to run syz repro with `./syz-execprog -executor=./syz-executor -repeat=20000 -procs=8 -cover=0 ~/repro.prog`.
> >
> >
> > Environment:
> >
> > Ubuntu 22.04 on Linux 5.15
> > QEMU emulator version 6.2.0
> > qemu-system-x86_64 \
> > -m 2G \
> > -smp 2 \
> > -kernel /home/wd/bzImage \
> > -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
> > -drive file=/home/wd/bullseye.img,format=raw \
> > -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
> > -net nic,model=e1000 \
> > -enable-kvm \
> > -nographic \
> > -pidfile vm.pid \
> > 2>&1 | tee vm.log
> >
> > If you fix this issue, please add the following tag to the commit:
> >
> > Reported-by: Jiacheng Xu <stitch@zju.edu.cn>
> >
Eric Dumazet Feb. 6, 2025, 1:32 p.m. UTC | #3
On Thu, Feb 6, 2025 at 2:22 PM Jiacheng Xu <stitch@zju.edu.cn> wrote:
>
> Hi Eric,
>
> We are a bit confused by your response. Could you please clarify whether you think this is simply a false positive report or if you are suggesting that the patch is ineffective?
>

Your patch is not correct, because we are not allowed to call
dev_close() under rcu_read_lock()

This might work for the particular repro and .config you were using,
but will trigger other syzbot reports quite fast.
Jiacheng Xu Feb. 7, 2025, 5:08 a.m. UTC | #4
Hi developers,

We update patch as follows. In this version, we avoid to call `dev_close` inside an RCU read-side critical section while still preventing the use of freed memory.

--- slip.c   2025-02-07 02:29:27.551293235 +0000
+++ slip.c      2025-02-07 02:46:57.156076645 +0000
@@ -717,21 +717,41 @@
 /* Collect hanged up channels */
 static void sl_sync(void)
 {
-       int i;
+       int i, count;
        struct net_device *dev;
+       struct net_device **devs;
        struct slip       *sl;

+       devs = kmalloc_array(slip_maxdev, sizeof(*devs), GFP_KERNEL);
+       if (!devs)
+               return;
+
+       rcu_read_lock();
+       for (i = 0; i< slip_maxdev; i++) {
+               dev = rcu_dereference(slip_devs[i]);
+               if (!dev)
+                       break;
+               dev_hold(dev);
+               devs[count++] = dev;
+       }
+       rcu_read_unlock();
+
        for (i = 0; i < slip_maxdev; i++) {
-               dev = slip_devs[i];
+               dev = devs[i];
                if (dev == NULL)
                        break;

                sl = netdev_priv(dev);
-               if (sl->tty || sl->leased)
+               if (sl->tty || sl->leased) {
+                       dev_put(dev);
                        continue;
+               }
                if (dev->flags & IFF_UP)
                        dev_close(dev);
+               dev_put(dev);
        }
+
+       kfree(devs);
 }

Best regards,
Jiacheng

> -----原始邮件-----
> 发件人: "Jiacheng Xu" <stitch@zju.edu.cn>
> 发送时间:2025-02-06 20:30:09 (星期四)
> 收件人: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org
> 抄送: wolffd@comp.nus.edu.sg
> 主题: [BUG] KASAN: slab-use-after-free in slip_open
> 
> Hi developers:
> 
> We are reporting a Linux issue using a modified version of Syzkaller.
> 
> HEAD commit: 4bbf9020 6.13.0-rc4
> git tree: upstream
> kernel config: https://github.com/google/syzkaller/blob/master/dashboard/config/linux/upstream-apparmor-kasan.config
> syz repro: https://drive.google.com/file/d/1XV9WHwMvK4eZIPuyjiWoTpyQ0FpDaUpT/view?usp=sharing
> C reproducer: As this is a race condition, a stable C reproducer is not available yet.
> 
> Environment:
> Ubuntu 22.04 on Linux 5.15
> QEMU emulator version 6.2.0
> qemu-system-x86_64 \
> -m 2G \
> -smp 2 \
> -kernel /home/wd/bzImage \
> -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
> -drive file=/home/wd/bullseye.img,format=raw \
> -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
> -net nic,model=e1000 \
> -enable-kvm \
> -nographic \
> -pidfile vm.pid \
> 2>&1 | tee vm.log
> 
> Steps to reproduce:
> 1. Setup a vm on given kernel.
> 2. Execute the syz reproducer with `./syz-execprog -executor=./syz-executor -repeat=20000 -procs=8 -cover=0 ~/repro.prog`
> 
> Description:
> The SLIP driver suffers from a Use-After-Free issue in sl_sync() due to unsynchronized access to net_device pointers stored in slip_devs[]. When a device is being freed (for example, via tty_release()/netdev_run_todo()), sl_sync() may access it after it has been freed.
> 
> Patch:
> We try to write a patch for the crash. And after applying the patch, the crash can no longer be triggered with the PoC.
> 
> --- slip.c      2025-02-06 12:26:25.690890378 +0000
> +++ slip.c      2025-02-06 12:29:30.554820899 +0000
> @@ -721,8 +721,9 @@
>         struct net_device *dev;
>         struct slip       *sl;
> 
> +       rcu_read_lock();
>         for (i = 0; i < slip_maxdev; i++) {
> -               dev = slip_devs[i];
> +               dev = rcu_dereference(slip_devs[i]);
>                 if (dev == NULL)
>                         break;
> 
> @@ -732,6 +733,7 @@
>                 if (dev->flags & IFF_UP)
>                         dev_close(dev);
>         }
> +       rcu_read_unlock();
>  }
> 
> 
> If you fix this issue, please add the following tag to the commit:
> Reported-by: Jiacheng Xu <stitch@zju.edu.cn>, Dylan Wolff <wolffd@comp.nus.edu.sg>
> ==================================================================
> BUG: KASAN: slab-use-after-free in sl_sync drivers/net/slip/slip.c:732 [inline]
> BUG: KASAN: slab-use-after-free in slip_open+0x293/0x1330 drivers/net/slip/slip.c:806
> Read of size 4 at addr ffff88805cfca0b0 by task syz-executor.2/46673
> 
> 
> CPU: 0 UID: 0 PID: 46673 Comm: syz-executor.2 Not tainted 6.13.0-rc4 #2
> 
> 
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
> 
> Sched_ext: serialise (enabled+all), task: runnable_at=-30ms
> Call Trace:
>  <TASK>
>  __dump_stack lib/dump_stack.c:94 [inline]
>  dump_stack_lvl+0x229/0x350 lib/dump_stack.c:120
>  print_address_description mm/kasan/report.c:378 [inline]
>  print_report+0x164/0x530 mm/kasan/report.c:489
>  kasan_report+0x147/0x180 mm/kasan/report.c:602
>  sl_sync drivers/net/slip/slip.c:732 [inline]
>  slip_open+0x293/0x1330 drivers/net/slip/slip.c:806
>  tty_ldisc_open+0xbd/0x120 drivers/tty/tty_ldisc.c:432
>  tty_set_ldisc+0x32b/0x5c0 drivers/tty/tty_ldisc.c:563
>  tiocsetd+0x126/0x170 drivers/tty/tty_io.c:2439
>  tty_ioctl+0xe5c/0x1090 drivers/tty/tty_io.c:2739
>  vfs_ioctl fs/ioctl.c:51 [inline]
>  __do_sys_ioctl fs/ioctl.c:906 [inline]
>  __se_sys_ioctl+0x266/0x350 fs/ioctl.c:892
>  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
>  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> RIP: 0033:0x7fed56a903ad
> Code: c3 e8 a7 2b 00 00 0f 1f 80 00 00 00 00 f3 0f 1e fa 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
> RSP: 002b:00007fed578b20c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
> RAX: ffffffffffffffda RBX: 00007fed56bcbf80 RCX: 00007fed56a903ad
> RDX: 0000000020000080 RSI: 0000000000005423 RDI: 0000000000000003
> RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000246 R12: 00007fed578b2640
> R13: 000000000000000e R14: 00007fed56a4fc90 R15: 00007fed578aa000
>  </TASK>
> 
> 
> Allocated by task 46683:
> 
> 
>  kasan_save_stack mm/kasan/common.c:47 [inline]
> 
>  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
>  poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
>  __kasan_kmalloc+0x89/0xa0 mm/kasan/common.c:394
>  kasan_kmalloc include/linux/kasan.h:260 [inline]
>  __do_kmalloc_node mm/slub.c:4298 [inline]
>  __kmalloc_node_noprof+0x28c/0x530 mm/slub.c:4304
>  __kvmalloc_node_noprof+0x70/0x180 mm/util.c:650
>  alloc_netdev_mqs+0xa7/0x1870 net/core/dev.c:11209
>  sl_alloc drivers/net/slip/slip.c:756 [inline]
>  slip_open+0x483/0x1330 drivers/net/slip/slip.c:817
>  tty_ldisc_open+0xbd/0x120 drivers/tty/tty_ldisc.c:432
>  tty_set_ldisc+0x32b/0x5c0 drivers/tty/tty_ldisc.c:563
>  tiocsetd+0x126/0x170 drivers/tty/tty_io.c:2439
>  tty_ioctl+0xe5c/0x1090 drivers/tty/tty_io.c:2739
>  vfs_ioctl fs/ioctl.c:51 [inline]
>  __do_sys_ioctl fs/ioctl.c:906 [inline]
>  __se_sys_ioctl+0x266/0x350 fs/ioctl.c:892
>  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
>  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> 
> 
> Freed by task 46682:
> 
> 
>  kasan_save_stack mm/kasan/common.c:47 [inline]
> 
>  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
>  kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:582
>  poison_slab_object mm/kasan/common.c:247 [inline]
>  __kasan_slab_free+0x5a/0x70 mm/kasan/common.c:264
>  kasan_slab_free include/linux/kasan.h:233 [inline]
>  slab_free_hook mm/slub.c:2353 [inline]
>  slab_free mm/slub.c:4613 [inline]
>  kfree+0x196/0x450 mm/slub.c:4761
>  device_release+0xcd/0x240
>  kobject_cleanup lib/kobject.c:689 [inline]
>  kobject_release lib/kobject.c:720 [inline]
>  kref_put include/linux/kref.h:65 [inline]
>  kobject_put+0x248/0x490 lib/kobject.c:737
>  netdev_run_todo+0x10e0/0x1280 net/core/dev.c:10924
>  tty_ldisc_kill+0xbf/0x150 drivers/tty/tty_ldisc.c:613
>  tty_ldisc_release+0x1ae/0x210 drivers/tty/tty_ldisc.c:781
>  tty_release_struct+0x2a/0x100 drivers/tty/tty_io.c:1690
>  tty_release+0xe4d/0x1460 drivers/tty/tty_io.c:1861
>  __fput+0x2ba/0xa80 fs/file_table.c:450
>  __fput_sync+0x180/0x1e0 fs/file_table.c:535
>  __do_sys_close fs/open.c:1554 [inline]
>  __se_sys_close fs/open.c:1539 [inline]
>  __x64_sys_close+0x93/0x120 fs/open.c:1539
>  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
>  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> 
> 
> The buggy address belongs to the object at ffff88805cfca000
> 
> 
>  which belongs to the cache kmalloc-cg-4k of size 4096
> 
> The buggy address is located 176 bytes inside of
>  freed 4096-byte region [ffff88805cfca000, ffff88805cfcb000)
> 
> 
> The buggy address belongs to the physical page:
> 
> 
> page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5cfc8
> 
> head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
> memcg:ffff888075c64a01
> flags: 0x4fff00000000040(head|node=1|zone=1|lastcpupid=0x7ff)
> page_type: f5(slab)
> raw: 04fff00000000040 ffff88801d44f500 dead000000000100 dead000000000122
> raw: 0000000000000000 0000000000040004 00000001f5000000 ffff888075c64a01
> head: 04fff00000000040 ffff88801d44f500 dead000000000100 dead000000000122
> head: 0000000000000000 0000000000040004 00000001f5000000 ffff888075c64a01
> head: 04fff00000000003 ffffea000173f201 ffffffffffffffff 0000000000000000
> head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
> page dumped because: kasan: bad access detected
> page_owner tracks the page as allocated
> page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9660, tgid 9660 (syz-executor.1), ts 93383578089, free_ts 93076565836
>  set_page_owner include/linux/page_owner.h:32 [inline]
>  post_alloc_hook+0x1f6/0x240 mm/page_alloc.c:1558
>  prep_new_page mm/page_alloc.c:1566 [inline]
>  get_page_from_freelist+0x3586/0x36d0 mm/page_alloc.c:3476
>  __alloc_pages_noprof+0x260/0x680 mm/page_alloc.c:4753
>  alloc_pages_mpol_noprof+0x3c8/0x650 mm/mempolicy.c:2269
>  alloc_slab_page+0x6a/0x110 mm/slub.c:2423
>  allocate_slab+0x5f/0x2b0 mm/slub.c:2589
>  new_slab mm/slub.c:2642 [inline]
>  ___slab_alloc+0xbdf/0x1490 mm/slub.c:3830
>  __slab_alloc mm/slub.c:3920 [inline]
>  __slab_alloc_node mm/slub.c:3995 [inline]
>  slab_alloc_node mm/slub.c:4156 [inline]
>  __do_kmalloc_node mm/slub.c:4297 [inline]
>  __kmalloc_node_track_caller_noprof+0x30f/0x520 mm/slub.c:4317
>  kmemdup_noprof+0x2b/0x60 mm/util.c:135
>  __addrconf_sysctl_register+0xb1/0x430 net/ipv6/addrconf.c:7221
>  addrconf_sysctl_register+0x1bd/0x220 net/ipv6/addrconf.c:7287
>  ipv6_add_dev+0xe13/0x13e0 net/ipv6/addrconf.c:456
>  addrconf_notify+0x6d8/0x1170 net/ipv6/addrconf.c:3674
>  notifier_call_chain+0x1c6/0x410 kernel/notifier.c:85
>  call_netdevice_notifiers_extack net/core/dev.c:2034 [inline]
>  call_netdevice_notifiers+0xd3/0x110 net/core/dev.c:2048
>  register_netdevice+0x190c/0x1da0 net/core/dev.c:10632
> page last free pid 100 tgid 100 stack trace:
>  reset_page_owner include/linux/page_owner.h:25 [inline]
>  free_pages_prepare mm/page_alloc.c:1127 [inline]
>  free_unref_folios+0xe03/0x1860 mm/page_alloc.c:2706
>  shrink_folio_list+0x4698/0x5c80 mm/vmscan.c:1483
>  evict_folios+0x3b12/0x5610 mm/vmscan.c:4593
>  try_to_shrink_lruvec+0x941/0xc10 mm/vmscan.c:4789
>  shrink_one+0x20e/0x870 mm/vmscan.c:4834
>  shrink_many mm/vmscan.c:4897 [inline]
>  lru_gen_shrink_node mm/vmscan.c:4975 [inline]
>  shrink_node+0x3862/0x3f20 mm/vmscan.c:5956
>  kswapd_shrink_node mm/vmscan.c:6785 [inline]
>  balance_pgdat mm/vmscan.c:6977 [inline]
>  kswapd+0x1c9f/0x36f0 mm/vmscan.c:7246
>  kthread+0x2c3/0x360 kernel/kthread.c:389
>  ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
>  ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
> 
> 
> Memory state around the buggy address:
> 
> 
>  ffff88805cfc9f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> 
>  ffff88805cfca000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> >ffff88805cfca080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>                                      ^
>  ffff88805cfca100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>  ffff88805cfca180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ==================================================================
> 
> Hi developers:
> 
> 
> We are reporting a Linux issue using a modified version of Syzkaller.
> 
> 
> HEAD commit: 4bbf9020 6.13.0-rc4
> 
> git tree: upstream
> kernel config: https://github.com/google/syzkaller/blob/master/dashboard/config/linux/upstream-apparmor-kasan.config
> syz repro: https://drive.google.com/file/d/1XV9WHwMvK4eZIPuyjiWoTpyQ0FpDaUpT/view?usp=sharing
> C reproducer: As this is a race condition, we cannot obtain a stable C reproducer.
> 
> 
> Description:
> 
> The SLIP driver suffers from a concurrent Use-After-Free issue in sl_sync() due to
> unsynchronized access to net_device pointers stored in slip_devs[]. When a
> device is being freed (for example, via tty_release()/netdev_run_todo()),
> sl_sync() may access it after it has been freed.
> 
> Steps to reproducer:
> 
> 1. Setup a vm on the given kernel.
> 2. Use syzkaller to run syz repro with `./syz-execprog -executor=./syz-executor -repeat=20000 -procs=8 -cover=0 ~/repro.prog`.
> 
> 
> Environment:
> 
> Ubuntu 22.04 on Linux 5.15
> QEMU emulator version 6.2.0
> qemu-system-x86_64 \
> -m 2G \
> -smp 2 \
> -kernel /home/wd/bzImage \
> -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
> -drive file=/home/wd/bullseye.img,format=raw \
> -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
> -net nic,model=e1000 \
> -enable-kvm \
> -nographic \
> -pidfile vm.pid \
> 2>&1 | tee vm.log
> 
> If you fix this issue, please add the following tag to the commit:
> 
> Reported-by: Jiacheng Xu <stitch@zju.edu.cn>
>
Eric Dumazet Feb. 7, 2025, 6:25 a.m. UTC | #5
On Fri, Feb 7, 2025 at 6:08 AM Jiacheng Xu <stitch@zju.edu.cn> wrote:
>
> Hi developers,
>
> We update patch as follows. In this version, we avoid to call `dev_close` inside an RCU read-side critical section while still preventing the use of freed memory.
>

This makes no sense for so many reasons.

At this point RTNL is held (drivers/net/slip/slip.c line 803)

rcu_read_lock() is not adding anything in a writer path.
This is really contrary to RCU rules to think that rcu_read_lock()
would be needed here.

Also what happens if kmalloc_array() fails ?

Please, find the root cause, explain what other part of the kernel is
not holding RTNL while it should,
then fix it ?

> --- slip.c   2025-02-07 02:29:27.551293235 +0000
> +++ slip.c      2025-02-07 02:46:57.156076645 +0000
> @@ -717,21 +717,41 @@
>  /* Collect hanged up channels */
>  static void sl_sync(void)
>  {
> -       int i;
> +       int i, count;
>         struct net_device *dev;
> +       struct net_device **devs;
>         struct slip       *sl;
>
> +       devs = kmalloc_array(slip_maxdev, sizeof(*devs), GFP_KERNEL);
> +       if (!devs)
> +               return;
> +
> +       rcu_read_lock();
> +       for (i = 0; i< slip_maxdev; i++) {
> +               dev = rcu_dereference(slip_devs[i]);
> +               if (!dev)
> +                       break;
> +               dev_hold(dev);
> +               devs[count++] = dev;
> +       }
> +       rcu_read_unlock();
> +
>         for (i = 0; i < slip_maxdev; i++) {
> -               dev = slip_devs[i];
> +               dev = devs[i];
>                 if (dev == NULL)
>                         break;
>
>                 sl = netdev_priv(dev);
> -               if (sl->tty || sl->leased)
> +               if (sl->tty || sl->leased) {
> +                       dev_put(dev);
>                         continue;
> +               }
>                 if (dev->flags & IFF_UP)
>                         dev_close(dev);
> +               dev_put(dev);
>         }
> +
> +       kfree(devs);
>  }
>
> Best regards,
> Jiacheng
>
> > -----原始邮件-----
> > 发件人: "Jiacheng Xu" <stitch@zju.edu.cn>
> > 发送时间:2025-02-06 20:30:09 (星期四)
> > 收件人: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org
> > 抄送: wolffd@comp.nus.edu.sg
> > 主题: [BUG] KASAN: slab-use-after-free in slip_open
> >
> > Hi developers:
> >
> > We are reporting a Linux issue using a modified version of Syzkaller.
> >
> > HEAD commit: 4bbf9020 6.13.0-rc4
> > git tree: upstream
> > kernel config: https://github.com/google/syzkaller/blob/master/dashboard/config/linux/upstream-apparmor-kasan.config
> > syz repro: https://drive.google.com/file/d/1XV9WHwMvK4eZIPuyjiWoTpyQ0FpDaUpT/view?usp=sharing
> > C reproducer: As this is a race condition, a stable C reproducer is not available yet.
> >
> > Environment:
> > Ubuntu 22.04 on Linux 5.15
> > QEMU emulator version 6.2.0
> > qemu-system-x86_64 \
> > -m 2G \
> > -smp 2 \
> > -kernel /home/wd/bzImage \
> > -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
> > -drive file=/home/wd/bullseye.img,format=raw \
> > -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
> > -net nic,model=e1000 \
> > -enable-kvm \
> > -nographic \
> > -pidfile vm.pid \
> > 2>&1 | tee vm.log
> >
> > Steps to reproduce:
> > 1. Setup a vm on given kernel.
> > 2. Execute the syz reproducer with `./syz-execprog -executor=./syz-executor -repeat=20000 -procs=8 -cover=0 ~/repro.prog`
> >
> > Description:
> > The SLIP driver suffers from a Use-After-Free issue in sl_sync() due to unsynchronized access to net_device pointers stored in slip_devs[]. When a device is being freed (for example, via tty_release()/netdev_run_todo()), sl_sync() may access it after it has been freed.
> >
> > Patch:
> > We try to write a patch for the crash. And after applying the patch, the crash can no longer be triggered with the PoC.
> >
> > --- slip.c      2025-02-06 12:26:25.690890378 +0000
> > +++ slip.c      2025-02-06 12:29:30.554820899 +0000
> > @@ -721,8 +721,9 @@
> >         struct net_device *dev;
> >         struct slip       *sl;
> >
> > +       rcu_read_lock();
> >         for (i = 0; i < slip_maxdev; i++) {
> > -               dev = slip_devs[i];
> > +               dev = rcu_dereference(slip_devs[i]);
> >                 if (dev == NULL)
> >                         break;
> >
> > @@ -732,6 +733,7 @@
> >                 if (dev->flags & IFF_UP)
> >                         dev_close(dev);
> >         }
> > +       rcu_read_unlock();
> >  }
> >
> >
> > If you fix this issue, please add the following tag to the commit:
> > Reported-by: Jiacheng Xu <stitch@zju.edu.cn>, Dylan Wolff <wolffd@comp.nus.edu.sg>
> > ==================================================================
> > BUG: KASAN: slab-use-after-free in sl_sync drivers/net/slip/slip.c:732 [inline]
> > BUG: KASAN: slab-use-after-free in slip_open+0x293/0x1330 drivers/net/slip/slip.c:806
> > Read of size 4 at addr ffff88805cfca0b0 by task syz-executor.2/46673
> >
> >
> > CPU: 0 UID: 0 PID: 46673 Comm: syz-executor.2 Not tainted 6.13.0-rc4 #2
> >
> >
> > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
> >
> > Sched_ext: serialise (enabled+all), task: runnable_at=-30ms
> > Call Trace:
> >  <TASK>
> >  __dump_stack lib/dump_stack.c:94 [inline]
> >  dump_stack_lvl+0x229/0x350 lib/dump_stack.c:120
> >  print_address_description mm/kasan/report.c:378 [inline]
> >  print_report+0x164/0x530 mm/kasan/report.c:489
> >  kasan_report+0x147/0x180 mm/kasan/report.c:602
> >  sl_sync drivers/net/slip/slip.c:732 [inline]
> >  slip_open+0x293/0x1330 drivers/net/slip/slip.c:806
> >  tty_ldisc_open+0xbd/0x120 drivers/tty/tty_ldisc.c:432
> >  tty_set_ldisc+0x32b/0x5c0 drivers/tty/tty_ldisc.c:563
> >  tiocsetd+0x126/0x170 drivers/tty/tty_io.c:2439
> >  tty_ioctl+0xe5c/0x1090 drivers/tty/tty_io.c:2739
> >  vfs_ioctl fs/ioctl.c:51 [inline]
> >  __do_sys_ioctl fs/ioctl.c:906 [inline]
> >  __se_sys_ioctl+0x266/0x350 fs/ioctl.c:892
> >  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
> >  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
> >  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> > RIP: 0033:0x7fed56a903ad
> > Code: c3 e8 a7 2b 00 00 0f 1f 80 00 00 00 00 f3 0f 1e fa 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
> > RSP: 002b:00007fed578b20c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
> > RAX: ffffffffffffffda RBX: 00007fed56bcbf80 RCX: 00007fed56a903ad
> > RDX: 0000000020000080 RSI: 0000000000005423 RDI: 0000000000000003
> > RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
> > R10: 0000000000000000 R11: 0000000000000246 R12: 00007fed578b2640
> > R13: 000000000000000e R14: 00007fed56a4fc90 R15: 00007fed578aa000
> >  </TASK>
> >
> >
> > Allocated by task 46683:
> >
> >
> >  kasan_save_stack mm/kasan/common.c:47 [inline]
> >
> >  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
> >  poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
> >  __kasan_kmalloc+0x89/0xa0 mm/kasan/common.c:394
> >  kasan_kmalloc include/linux/kasan.h:260 [inline]
> >  __do_kmalloc_node mm/slub.c:4298 [inline]
> >  __kmalloc_node_noprof+0x28c/0x530 mm/slub.c:4304
> >  __kvmalloc_node_noprof+0x70/0x180 mm/util.c:650
> >  alloc_netdev_mqs+0xa7/0x1870 net/core/dev.c:11209
> >  sl_alloc drivers/net/slip/slip.c:756 [inline]
> >  slip_open+0x483/0x1330 drivers/net/slip/slip.c:817
> >  tty_ldisc_open+0xbd/0x120 drivers/tty/tty_ldisc.c:432
> >  tty_set_ldisc+0x32b/0x5c0 drivers/tty/tty_ldisc.c:563
> >  tiocsetd+0x126/0x170 drivers/tty/tty_io.c:2439
> >  tty_ioctl+0xe5c/0x1090 drivers/tty/tty_io.c:2739
> >  vfs_ioctl fs/ioctl.c:51 [inline]
> >  __do_sys_ioctl fs/ioctl.c:906 [inline]
> >  __se_sys_ioctl+0x266/0x350 fs/ioctl.c:892
> >  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
> >  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
> >  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> >
> >
> > Freed by task 46682:
> >
> >
> >  kasan_save_stack mm/kasan/common.c:47 [inline]
> >
> >  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
> >  kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:582
> >  poison_slab_object mm/kasan/common.c:247 [inline]
> >  __kasan_slab_free+0x5a/0x70 mm/kasan/common.c:264
> >  kasan_slab_free include/linux/kasan.h:233 [inline]
> >  slab_free_hook mm/slub.c:2353 [inline]
> >  slab_free mm/slub.c:4613 [inline]
> >  kfree+0x196/0x450 mm/slub.c:4761
> >  device_release+0xcd/0x240
> >  kobject_cleanup lib/kobject.c:689 [inline]
> >  kobject_release lib/kobject.c:720 [inline]
> >  kref_put include/linux/kref.h:65 [inline]
> >  kobject_put+0x248/0x490 lib/kobject.c:737
> >  netdev_run_todo+0x10e0/0x1280 net/core/dev.c:10924
> >  tty_ldisc_kill+0xbf/0x150 drivers/tty/tty_ldisc.c:613
> >  tty_ldisc_release+0x1ae/0x210 drivers/tty/tty_ldisc.c:781
> >  tty_release_struct+0x2a/0x100 drivers/tty/tty_io.c:1690
> >  tty_release+0xe4d/0x1460 drivers/tty/tty_io.c:1861
> >  __fput+0x2ba/0xa80 fs/file_table.c:450
> >  __fput_sync+0x180/0x1e0 fs/file_table.c:535
> >  __do_sys_close fs/open.c:1554 [inline]
> >  __se_sys_close fs/open.c:1539 [inline]
> >  __x64_sys_close+0x93/0x120 fs/open.c:1539
> >  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
> >  do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
> >  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> >
> >
> > The buggy address belongs to the object at ffff88805cfca000
> >
> >
> >  which belongs to the cache kmalloc-cg-4k of size 4096
> >
> > The buggy address is located 176 bytes inside of
> >  freed 4096-byte region [ffff88805cfca000, ffff88805cfcb000)
> >
> >
> > The buggy address belongs to the physical page:
> >
> >
> > page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5cfc8
> >
> > head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
> > memcg:ffff888075c64a01
> > flags: 0x4fff00000000040(head|node=1|zone=1|lastcpupid=0x7ff)
> > page_type: f5(slab)
> > raw: 04fff00000000040 ffff88801d44f500 dead000000000100 dead000000000122
> > raw: 0000000000000000 0000000000040004 00000001f5000000 ffff888075c64a01
> > head: 04fff00000000040 ffff88801d44f500 dead000000000100 dead000000000122
> > head: 0000000000000000 0000000000040004 00000001f5000000 ffff888075c64a01
> > head: 04fff00000000003 ffffea000173f201 ffffffffffffffff 0000000000000000
> > head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
> > page dumped because: kasan: bad access detected
> > page_owner tracks the page as allocated
> > page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9660, tgid 9660 (syz-executor.1), ts 93383578089, free_ts 93076565836
> >  set_page_owner include/linux/page_owner.h:32 [inline]
> >  post_alloc_hook+0x1f6/0x240 mm/page_alloc.c:1558
> >  prep_new_page mm/page_alloc.c:1566 [inline]
> >  get_page_from_freelist+0x3586/0x36d0 mm/page_alloc.c:3476
> >  __alloc_pages_noprof+0x260/0x680 mm/page_alloc.c:4753
> >  alloc_pages_mpol_noprof+0x3c8/0x650 mm/mempolicy.c:2269
> >  alloc_slab_page+0x6a/0x110 mm/slub.c:2423
> >  allocate_slab+0x5f/0x2b0 mm/slub.c:2589
> >  new_slab mm/slub.c:2642 [inline]
> >  ___slab_alloc+0xbdf/0x1490 mm/slub.c:3830
> >  __slab_alloc mm/slub.c:3920 [inline]
> >  __slab_alloc_node mm/slub.c:3995 [inline]
> >  slab_alloc_node mm/slub.c:4156 [inline]
> >  __do_kmalloc_node mm/slub.c:4297 [inline]
> >  __kmalloc_node_track_caller_noprof+0x30f/0x520 mm/slub.c:4317
> >  kmemdup_noprof+0x2b/0x60 mm/util.c:135
> >  __addrconf_sysctl_register+0xb1/0x430 net/ipv6/addrconf.c:7221
> >  addrconf_sysctl_register+0x1bd/0x220 net/ipv6/addrconf.c:7287
> >  ipv6_add_dev+0xe13/0x13e0 net/ipv6/addrconf.c:456
> >  addrconf_notify+0x6d8/0x1170 net/ipv6/addrconf.c:3674
> >  notifier_call_chain+0x1c6/0x410 kernel/notifier.c:85
> >  call_netdevice_notifiers_extack net/core/dev.c:2034 [inline]
> >  call_netdevice_notifiers+0xd3/0x110 net/core/dev.c:2048
> >  register_netdevice+0x190c/0x1da0 net/core/dev.c:10632
> > page last free pid 100 tgid 100 stack trace:
> >  reset_page_owner include/linux/page_owner.h:25 [inline]
> >  free_pages_prepare mm/page_alloc.c:1127 [inline]
> >  free_unref_folios+0xe03/0x1860 mm/page_alloc.c:2706
> >  shrink_folio_list+0x4698/0x5c80 mm/vmscan.c:1483
> >  evict_folios+0x3b12/0x5610 mm/vmscan.c:4593
> >  try_to_shrink_lruvec+0x941/0xc10 mm/vmscan.c:4789
> >  shrink_one+0x20e/0x870 mm/vmscan.c:4834
> >  shrink_many mm/vmscan.c:4897 [inline]
> >  lru_gen_shrink_node mm/vmscan.c:4975 [inline]
> >  shrink_node+0x3862/0x3f20 mm/vmscan.c:5956
> >  kswapd_shrink_node mm/vmscan.c:6785 [inline]
> >  balance_pgdat mm/vmscan.c:6977 [inline]
> >  kswapd+0x1c9f/0x36f0 mm/vmscan.c:7246
> >  kthread+0x2c3/0x360 kernel/kthread.c:389
> >  ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
> >  ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
> >
> >
> > Memory state around the buggy address:
> >
> >
> >  ffff88805cfc9f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >
> >  ffff88805cfca000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> > >ffff88805cfca080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> >                                      ^
> >  ffff88805cfca100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> >  ffff88805cfca180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> > ==================================================================
> >
> > Hi developers:
> >
> >
> > We are reporting a Linux issue using a modified version of Syzkaller.
> >
> >
> > HEAD commit: 4bbf9020 6.13.0-rc4
> >
> > git tree: upstream
> > kernel config: https://github.com/google/syzkaller/blob/master/dashboard/config/linux/upstream-apparmor-kasan.config
> > syz repro: https://drive.google.com/file/d/1XV9WHwMvK4eZIPuyjiWoTpyQ0FpDaUpT/view?usp=sharing
> > C reproducer: As this is a race condition, we cannot obtain a stable C reproducer.
> >
> >
> > Description:
> >
> > The SLIP driver suffers from a concurrent Use-After-Free issue in sl_sync() due to
> > unsynchronized access to net_device pointers stored in slip_devs[]. When a
> > device is being freed (for example, via tty_release()/netdev_run_todo()),
> > sl_sync() may access it after it has been freed.
> >
> > Steps to reproducer:
> >
> > 1. Setup a vm on the given kernel.
> > 2. Use syzkaller to run syz repro with `./syz-execprog -executor=./syz-executor -repeat=20000 -procs=8 -cover=0 ~/repro.prog`.
> >
> >
> > Environment:
> >
> > Ubuntu 22.04 on Linux 5.15
> > QEMU emulator version 6.2.0
> > qemu-system-x86_64 \
> > -m 2G \
> > -smp 2 \
> > -kernel /home/wd/bzImage \
> > -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
> > -drive file=/home/wd/bullseye.img,format=raw \
> > -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
> > -net nic,model=e1000 \
> > -enable-kvm \
> > -nographic \
> > -pidfile vm.pid \
> > 2>&1 | tee vm.log
> >
> > If you fix this issue, please add the following tag to the commit:
> >
> > Reported-by: Jiacheng Xu <stitch@zju.edu.cn>
> >
diff mbox series

Patch

--- slip.c      2025-02-06 12:26:25.690890378 +0000
+++ slip.c      2025-02-06 12:29:30.554820899 +0000
@@ -721,8 +721,9 @@ 
        struct net_device *dev;
        struct slip       *sl;

+       rcu_read_lock();
        for (i = 0; i < slip_maxdev; i++) {
-               dev = slip_devs[i];
+               dev = rcu_dereference(slip_devs[i]);
                if (dev == NULL)
                        break;

@@ -732,6 +733,7 @@ 
                if (dev->flags & IFF_UP)
                        dev_close(dev);
        }
+       rcu_read_unlock();
 }