KASAN: slab-out-of-bounds Read in getname_kernel (2)
Subsystems (4)
syzbot
syzbotHello,
syzbot found the following issue on:
HEAD commit: 3bd7d7488169 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: upstream console+strace: https://syzkaller.appspot.com/x/log.txt?x=13732cc6e80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=16d8ba06e80000 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=136fd5b2e80000
Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/99b3f103aa0b/disk-3bd7d748.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/32f8e3e696ce/vmlinux-3bd7d748.xz
kernel image: https://storage.googleapis.com/syzbot-assets/cb20a5445c11/bzImage-3bd7d748.xz
mounted in repro: https://storage.googleapis.com/syzbot-assets/4f5365674997/mount_0.gz
The issue was bisected to:
commit 9974d37ea75f01b47d16072b5dad305bd8d23fcc
Author: Liu Jian <[email protected]> Date: Tue Jun 28 12:36:16 2022 +0000
skmsg: Fix invalid last sg check in sk_msg_recvmsg()
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=172b998ae80000 final oops: https://syzkaller.appspot.com/x/report.txt?x=14ab998ae80000 console output: https://syzkaller.appspot.com/x/log.txt?x=10ab998ae80000
IMPORTANT: if you fix the issue, please add the following tag to the commit:
BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE_VALID (0x2)
==================================================================
BUG: KASAN: slab-out-of-bounds in strlen+0x58/0x70 lib/string.c:418 Read of size 1 at addr ffff88801d7f2a28 by task syz-executor424/5057 CPU: 1 PID: 5057 Comm: syz-executor424 Not tainted 6.7.0-rc5-syzkaller-00200-g3bd7d7488169 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:364 [inline] print_report+0x163/0x540 mm/kasan/report.c:475 kasan_report+0x142/0x170 mm/kasan/report.c:588 strlen+0x58/0x70 lib/string.c:418 getname_kernel+0x1d/0x2e0 fs/namei.c:226 kern_path+0x1d/0x50 fs/namei.c:2609 lookup_bdev block/bdev.c:979 [inline] bdev_open_by_path+0xd1/0x540 block/bdev.c:901 btrfs_init_dev_replace_tgtdev fs/btrfs/dev-replace.c:260 [inline] btrfs_dev_replace_start fs/btrfs/dev-replace.c:638 [inline] btrfs_dev_replace_by_ioctl+0x41b/0x2010 fs/btrfs/dev-replace.c:747 btrfs_ioctl_dev_replace+0x2c9/0x390 fs/btrfs/ioctl.c:3299 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f8e8ffdc079 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 61 17 00 00 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 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffe15cbe138 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007ffe15cbe308 RCX: 00007f8e8ffdc079 RDX: 0000000020000540 RSI: 00000000ca289435 RDI: 0000000000000005 RBP: 00007f8e90054610 R08: 00007ffe15cbe308 R09: 00007ffe15cbe308 R10: 00007ffe15cbe308 R11: 0000000000000246 R12: 0000000000000001 R13: 00007ffe15cbe2f8 R14: 0000000000000001 R15: 0000000000000001 </TASK> Allocated by task 5057: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4f/0x70 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:374 [inline] __kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:383 kasan_kmalloc include/linux/kasan.h:198 [inline] __do_kmalloc_node mm/slab_common.c:1007 [inline] __kmalloc_node_track_caller+0xb1/0x190 mm/slab_common.c:1027 memdup_user+0x2b/0xc0 mm/util.c:197 btrfs_ioctl_dev_replace+0xb8/0x390 fs/btrfs/ioctl.c:3286 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b The buggy address belongs to the object at ffff88801d7f2000 which belongs to the cache kmalloc-4k of size 4096
The buggy address is located 0 bytes to the right of
allocated 2600-byte region [ffff88801d7f2000, ffff88801d7f2a28)
The buggy address belongs to the physical page:
page:ffffea000075fc00 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1d7f0 head:ffffea000075fc00 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0xfff00000000840(slab|head|node=0|zone=1|lastcpupid=0x7ff)page_type: 0xffffffff()
raw: 00fff00000000840 ffff888012c42140 ffffea00007b5600 0000000000000002
raw: 0000000000000000 0000000080040004 00000001ffffffff 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 0xd2040(__GFP_IO|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 4716, tgid 4716 (ifup), ts 29920494589, free_ts 29905444571
set_page_owner include/linux/page_owner.h:31 [inline]
post_alloc_hook+0x1e6/0x210 mm/page_alloc.c:1537
prep_new_page mm/page_alloc.c:1544 [inline]
get_page_from_freelist+0x33ea/0x3570 mm/page_alloc.c:3312
__alloc_pages+0x255/0x680 mm/page_alloc.c:4568
alloc_pages_mpol+0x3de/0x640 mm/mempolicy.c:2133
alloc_slab_page+0x6a/0x170 mm/slub.c:1870
allocate_slab mm/slub.c:2017 [inline]
new_slab+0x84/0x2f0 mm/slub.c:2070
___slab_alloc+0xc8a/0x1330 mm/slub.c:3223
__slab_alloc mm/slub.c:3322 [inline]
__slab_alloc_node mm/slub.c:3375 [inline]
slab_alloc_node mm/slub.c:3468 [inline]
__kmem_cache_alloc_node+0x21d/0x300 mm/slub.c:3517
__do_kmalloc_node mm/slab_common.c:1006 [inline]
__kmalloc+0xa2/0x1a0 mm/slab_common.c:1020
kmalloc include/linux/slab.h:604 [inline]
tomoyo_realpath_from_path+0xcf/0x5e0 security/tomoyo/realpath.c:251
tomoyo_get_realpath security/tomoyo/file.c:151 [inline]
tomoyo_check_open_permission+0x255/0x500 security/tomoyo/file.c:771
security_file_open+0x63/0xa0 security/security.c:2836
do_dentry_open+0x327/0x1590 fs/open.c:935
do_open fs/namei.c:3622 [inline]
path_openat+0x2849/0x3290 fs/namei.c:3779
do_filp_open+0x234/0x490 fs/namei.c:3809
do_sys_openat2+0x13e/0x1d0 fs/open.c:1440
page last free stack trace:
reset_page_owner include/linux/page_owner.h:24 [inline]
free_pages_prepare mm/page_alloc.c:1137 [inline]
free_unref_page_prepare+0x931/0xa60 mm/page_alloc.c:2347
free_unref_page+0x37/0x3f0 mm/page_alloc.c:2487
discard_slab mm/slub.c:2116 [inline]
__unfreeze_partials+0x1e0/0x220 mm/slub.c:2655
put_cpu_partial+0x17b/0x250 mm/slub.c:2731
__slab_free+0x2b6/0x390 mm/slub.c:3679
qlink_free mm/kasan/quarantine.c:168 [inline]
qlist_free_all+0x75/0xe0 mm/kasan/quarantine.c:187
kasan_quarantine_reduce+0x14b/0x160 mm/kasan/quarantine.c:294
__kasan_slab_alloc+0x23/0x70 mm/kasan/common.c:305
kasan_slab_alloc include/linux/kasan.h:188 [inline]
slab_post_alloc_hook+0x6c/0x3c0 mm/slab.h:763
slab_alloc_node mm/slub.c:3478 [inline]
__kmem_cache_alloc_node+0x1d0/0x300 mm/slub.c:3517
__do_kmalloc_node mm/slab_common.c:1006 [inline]
__kmalloc+0xa2/0x1a0 mm/slab_common.c:1020
kmalloc include/linux/slab.h:604 [inline]
tomoyo_realpath_from_path+0xcf/0x5e0 security/tomoyo/realpath.c:251
tomoyo_get_realpath security/tomoyo/file.c:151 [inline]
tomoyo_path_perm+0x2b7/0x730 security/tomoyo/file.c:822
security_inode_getattr+0xd3/0x120 security/security.c:2153
vfs_getattr+0x46/0x430 fs/stat.c:173
vfs_fstat fs/stat.c:198 [inline]
vfs_fstatat+0xd6/0x190 fs/stat.c:295
Memory state around the buggy address:
ffff88801d7f2900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88801d7f2980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88801d7f2a00: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
^
ffff88801d7f2a80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88801d7f2b00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================---
This report is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at [email protected].
syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot. For information about bisection process see: https://goo.gl/tpsmEJ#bisection
If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title
If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.
If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)
If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report
If you want to undo deduplication, reply with:
#syz undup
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
fs/btrfs/dev-replace.c +2 -1
@@ -741,7 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, }if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + args->start.tgtdev_name[0] == '')return -EINVAL ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,
syzbot
syzbotsyzbot tried to test the proposed patch but the build/boot failed:
Hello,
syzbot tried to test the proposed patch but the build/boot failed:
fs/btrfs/dev-replace.c:745:36: warning: empty character constant [-Winvalid-pp-token] fs/btrfs/dev-replace.c:745:36: error: expected expression
Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=1392a8d6e80000
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
fs/btrfs/dev-replace.c +2 -1
@@ -741,7 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, }if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + args->start.tgtdev_name[0 ] ==0 )return -EINVAL ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,
syzbot
syzbotsyzbot has tested the proposed patch but the reproducer is still triggering an issue:
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
KASAN: slab-out-of-bounds Read in getname_kernel
BTRFS info (device loop0): disabling free space tree
BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE (0x1) BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE_VALID (0x2)
==================================================================
BUG: KASAN: slab-out-of-bounds in strlen+0x58/0x70 lib/string.c:418 Read of size 1 at addr ffff88814b62aa28 by task syz-executor.0/5482 CPU: 0 PID: 5482 Comm: syz-executor.0 Not tainted 6.7.0-rc5-syzkaller-00200-g3bd7d7488169-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:364 [inline] print_report+0x163/0x540 mm/kasan/report.c:475 kasan_report+0x142/0x170 mm/kasan/report.c:588 strlen+0x58/0x70 lib/string.c:418 getname_kernel+0x1d/0x2e0 fs/namei.c:226 kern_path+0x1d/0x50 fs/namei.c:2609 lookup_bdev block/bdev.c:979 [inline] bdev_open_by_path+0xd1/0x540 block/bdev.c:901 btrfs_init_dev_replace_tgtdev fs/btrfs/dev-replace.c:260 [inline] btrfs_dev_replace_start fs/btrfs/dev-replace.c:638 [inline] btrfs_dev_replace_by_ioctl+0x41b/0x2010 fs/btrfs/dev-replace.c:748 btrfs_ioctl_dev_replace+0x2c9/0x390 fs/btrfs/ioctl.c:3299 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f617807cba9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f6178dd40c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f617819bf80 RCX: 00007f617807cba9 RDX: 0000000020000540 RSI: 00000000ca289435 RDI: 0000000000000005 RBP: 00007f61780c847a R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007f617819bf80 R15: 00007ffcbe283518 </TASK> Allocated by task 5482: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4f/0x70 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:374 [inline] __kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:383 kasan_kmalloc include/linux/kasan.h:198 [inline] __do_kmalloc_node mm/slab_common.c:1007 [inline] __kmalloc_node_track_caller+0xb1/0x190 mm/slab_common.c:1027 memdup_user+0x2b/0xc0 mm/util.c:197 btrfs_ioctl_dev_replace+0xb8/0x390 fs/btrfs/ioctl.c:3286 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b The buggy address belongs to the object at ffff88814b62a000 which belongs to the cache kmalloc-4k of size 4096
The buggy address is located 0 bytes to the right of
allocated 2600-byte region [ffff88814b62a000, ffff88814b62aa28)
The buggy address belongs to the physical page:
page:ffffea00052d8a00 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x14b628 head:ffffea00052d8a00 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x57ff00000000840(slab|head|node=1|zone=2|lastcpupid=0x7ff)page_type: 0xffffffff()
raw: 057ff00000000840 ffff888012c42140 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000040004 00000001ffffffff 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 1, tgid 1 (swapper/0), ts 12558368773, free_ts 0 set_page_owner include/linux/page_owner.h:31 [inline] post_alloc_hook+0x1e6/0x210 mm/page_alloc.c:1537 prep_new_page mm/page_alloc.c:1544 [inline] get_page_from_freelist+0x33ea/0x3570 mm/page_alloc.c:3312 __alloc_pages+0x255/0x680 mm/page_alloc.c:4568 alloc_pages_mpol+0x3de/0x640 mm/mempolicy.c:2133 alloc_slab_page+0x6a/0x170 mm/slub.c:1870 allocate_slab mm/slub.c:2017 [inline] new_slab+0x84/0x2f0 mm/slub.c:2070 ___slab_alloc+0xc8a/0x1330 mm/slub.c:3223 __slab_alloc mm/slub.c:3322 [inline] __slab_alloc_node mm/slub.c:3375 [inline] slab_alloc_node mm/slub.c:3468 [inline] __kmem_cache_alloc_node+0x21d/0x300 mm/slub.c:3517 __do_kmalloc_node mm/slab_common.c:1006 [inline] __kmalloc_node_track_caller+0xa0/0x190 mm/slab_common.c:1027 kmalloc_reserve+0xf3/0x260 net/core/skbuff.c:582 __alloc_skb+0x1b1/0x420 net/core/skbuff.c:651 alloc_skb include/linux/skbuff.h:1286 [inline] nlmsg_new include/net/netlink.h:1010 [inline] ctrl_build_mcgrp_msg net/netlink/genetlink.c:1264 [inline] genl_ctrl_event+0x18e/0xc80 net/netlink/genetlink.c:1350 genl_register_family+0x13df/0x17a0 net/netlink/genetlink.c:694 handshake_init+0x2b/0xc0 net/handshake/netlink.c:255 do_one_initcall+0x234/0x810 init/main.c:1236 do_initcall_level+0x157/0x210 init/main.c:1298
page_owner free stack trace missing
Memory state around the buggy address:
ffff88814b62a900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88814b62a980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88814b62aa00: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
^
ffff88814b62aa80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88814b62ab00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git console output: https://syzkaller.appspot.com/x/log.txt?x=123685aee80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=131d1876e80000
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
fs/btrfs/dev-replace.c +2 -1
@@ -741,7 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, }if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + !args->start.tgtdev_name[0 ])return -EINVAL ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,
mm/util.c +1 -1
@@ -194,7 +194,7 @@ void *memdup_user(const void __user *src, size_t len) {void *p; - p =kmalloc_track_caller (len,GFP_USER | __GFP_NOWARN); + p =kmalloc_track_caller (len,GFP_USER | __GFP_NOWARN | __GFP_ZERO);if (!p)return ERR_PTR (-ENOMEM );
syzbot
syzbotsyzbot has tested the proposed patch but the reproducer is still triggering an issue:
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
KASAN: slab-out-of-bounds Read in getname_kernel
BTRFS info (device loop0): disabling free space tree
BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE (0x1) BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE_VALID (0x2)
==================================================================
BUG: KASAN: slab-out-of-bounds in strlen+0x58/0x70 lib/string.c:418 Read of size 1 at addr ffff88807f73ea28 by task syz-executor.0/5483 CPU: 0 PID: 5483 Comm: syz-executor.0 Not tainted 6.7.0-rc5-syzkaller-00200-g3bd7d7488169-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:364 [inline] print_report+0x163/0x540 mm/kasan/report.c:475 kasan_report+0x142/0x170 mm/kasan/report.c:588 strlen+0x58/0x70 lib/string.c:418 getname_kernel+0x1d/0x2e0 fs/namei.c:226 kern_path+0x1d/0x50 fs/namei.c:2609 lookup_bdev block/bdev.c:979 [inline] bdev_open_by_path+0xd1/0x540 block/bdev.c:901 btrfs_init_dev_replace_tgtdev fs/btrfs/dev-replace.c:260 [inline] btrfs_dev_replace_start fs/btrfs/dev-replace.c:638 [inline] btrfs_dev_replace_by_ioctl+0x41b/0x2010 fs/btrfs/dev-replace.c:748 btrfs_ioctl_dev_replace+0x2c9/0x390 fs/btrfs/ioctl.c:3299 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7efc28c7cba9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007efc299370c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007efc28d9bf80 RCX: 00007efc28c7cba9 RDX: 0000000020000540 RSI: 00000000ca289435 RDI: 0000000000000005 RBP: 00007efc28cc847a R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007efc28d9bf80 R15: 00007ffd45118af8 </TASK> Allocated by task 5483: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4f/0x70 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:374 [inline] __kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:383 kasan_kmalloc include/linux/kasan.h:198 [inline] __do_kmalloc_node mm/slab_common.c:1007 [inline] __kmalloc_node_track_caller+0xb1/0x190 mm/slab_common.c:1027 memdup_user+0x2b/0xc0 mm/util.c:197 btrfs_ioctl_dev_replace+0xb8/0x390 fs/btrfs/ioctl.c:3286 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b The buggy address belongs to the object at ffff88807f73e000 which belongs to the cache kmalloc-4k of size 4096
The buggy address is located 0 bytes to the right of
allocated 2600-byte region [ffff88807f73e000, ffff88807f73ea28)
The buggy address belongs to the physical page:
page:ffffea0001fdce00 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x7f738 head:ffffea0001fdce00 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0xfff00000000840(slab|head|node=0|zone=1|lastcpupid=0x7ff)page_type: 0xffffffff()
raw: 00fff00000000840 ffff888012c42140 dead000000000122 0000000000000000
raw: 0000000000000000 0000000000040004 00000001ffffffff 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 0x1d2040(__GFP_IO|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC|__GFP_HARDWALL), pid 5519, tgid 5519 (sed), ts 85994199611, free_ts 85914192085
set_page_owner include/linux/page_owner.h:31 [inline]
post_alloc_hook+0x1e6/0x210 mm/page_alloc.c:1537
prep_new_page mm/page_alloc.c:1544 [inline]
get_page_from_freelist+0x33ea/0x3570 mm/page_alloc.c:3312
__alloc_pages+0x255/0x680 mm/page_alloc.c:4568
alloc_pages_mpol+0x3de/0x640 mm/mempolicy.c:2133
alloc_slab_page+0x6a/0x170 mm/slub.c:1870
allocate_slab mm/slub.c:2017 [inline]
new_slab+0x84/0x2f0 mm/slub.c:2070
___slab_alloc+0xc8a/0x1330 mm/slub.c:3223
__slab_alloc mm/slub.c:3322 [inline]
__slab_alloc_node mm/slub.c:3375 [inline]
slab_alloc_node mm/slub.c:3468 [inline]
__kmem_cache_alloc_node+0x21d/0x300 mm/slub.c:3517
__do_kmalloc_node mm/slab_common.c:1006 [inline]
__kmalloc+0xa2/0x1a0 mm/slab_common.c:1020
kmalloc include/linux/slab.h:604 [inline]
tomoyo_realpath_from_path+0xcf/0x5e0 security/tomoyo/realpath.c:251
tomoyo_get_realpath security/tomoyo/file.c:151 [inline]
tomoyo_path_perm+0x2b7/0x730 security/tomoyo/file.c:822
security_inode_getattr+0xd3/0x120 security/security.c:2153
vfs_getattr+0x46/0x430 fs/stat.c:173
vfs_fstat fs/stat.c:198 [inline]
vfs_fstatat+0xd6/0x190 fs/stat.c:295
__do_sys_newfstatat fs/stat.c:463 [inline]
__se_sys_newfstatat fs/stat.c:457 [inline]
__x64_sys_newfstatat+0x117/0x190 fs/stat.c:457
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83
page last free stack trace:
reset_page_owner include/linux/page_owner.h:24 [inline]
free_pages_prepare mm/page_alloc.c:1137 [inline]
free_unref_page_prepare+0x931/0xa60 mm/page_alloc.c:2347
free_unref_page+0x37/0x3f0 mm/page_alloc.c:2487
discard_slab mm/slub.c:2116 [inline]
__unfreeze_partials+0x1e0/0x220 mm/slub.c:2655
put_cpu_partial+0x17b/0x250 mm/slub.c:2731
__slab_free+0x2b6/0x390 mm/slub.c:3679
qlink_free mm/kasan/quarantine.c:168 [inline]
qlist_free_all+0x75/0xe0 mm/kasan/quarantine.c:187
kasan_quarantine_reduce+0x14b/0x160 mm/kasan/quarantine.c:294
__kasan_slab_alloc+0x23/0x70 mm/kasan/common.c:305
kasan_slab_alloc include/linux/kasan.h:188 [inline]
slab_post_alloc_hook+0x6c/0x3c0 mm/slab.h:763
slab_alloc_node mm/slub.c:3478 [inline]
__kmem_cache_alloc_node+0x1d0/0x300 mm/slub.c:3517
__do_kmalloc_node mm/slab_common.c:1006 [inline]
__kmalloc+0xa2/0x1a0 mm/slab_common.c:1020
kmalloc include/linux/slab.h:604 [inline]
tomoyo_realpath_from_path+0xcf/0x5e0 security/tomoyo/realpath.c:251
tomoyo_get_realpath security/tomoyo/file.c:151 [inline]
tomoyo_path_perm+0x2b7/0x730 security/tomoyo/file.c:822
security_inode_getattr+0xd3/0x120 security/security.c:2153
vfs_getattr+0x46/0x430 fs/stat.c:173
vfs_fstat fs/stat.c:198 [inline]
vfs_fstatat+0xd6/0x190 fs/stat.c:295
Memory state around the buggy address:
ffff88807f73e900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88807f73e980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88807f73ea00: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
^
ffff88807f73ea80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88807f73eb00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git console output: https://syzkaller.appspot.com/x/log.txt?x=10530592e80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=145803e1e80000
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
fs/btrfs/dev-replace.c +2 -1
@@ -741,7 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, }if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + !args->start.tgtdev_name[0 ])return -EINVAL ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,
fs/btrfs/ioctl.c +8 -10
@@ -3272,7 +3272,7 @@ static long btrfs_ioctl_get_dev_stats(struct btrfs_fs_info *fs_info,static long btrfs_ioctl_dev_replace (struct btrfs_fs_info *fs_info,void __user *arg) { -struct btrfs_ioctl_dev_replace_args *p; +struct btrfs_ioctl_dev_replace_args p = {};int ret;if (!capable (CAP_SYS_ADMIN ))
@@ -3283,11 +3283,10 @@ static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info,return -EINVAL ; } - p =memdup_user (arg,sizeof (*p)); -if (IS_ERR (p)) -return PTR_ERR (p); +if (copy_from_user (&p, arg,sizeof (p))) +return -EINVAL ; -switch (p->cmd) { +switch (p.cmd) {case BTRFS_IOCTL_DEV_REPLACE_CMD_START :if (sb_rdonly (fs_info->sb)) { ret = -EROFS ;
@@ -3296,16 +3295,16 @@ static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info,if (!btrfs_exclop_start (fs_info,BTRFS_EXCLOP_DEV_REPLACE )) { ret =BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS ; }else { - ret =btrfs_dev_replace_by_ioctl (fs_info, p); + ret =btrfs_dev_replace_by_ioctl (fs_info, &p);btrfs_exclop_finish (fs_info); }break ;case BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS : -btrfs_dev_replace_status (fs_info, p); +btrfs_dev_replace_status (fs_info, &p); ret =0 ;break ;case BTRFS_IOCTL_DEV_REPLACE_CMD_CANCEL : - p->result =btrfs_dev_replace_cancel (fs_info); + p.result =btrfs_dev_replace_cancel (fs_info); ret =0 ;break ;default :
@@ -3313,10 +3312,9 @@ static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info,break ; } -if ((ret ==0 || ret == -ECANCELED ) &©_to_user (arg, p,sizeof (*p))) +if ((ret ==0 || ret == -ECANCELED ) &©_to_user (arg, &p,sizeof (p))) ret = -EFAULT ; out: -kfree (p);return ret; }
syzbot
syzbotsyzbot has tested the proposed patch but the reproducer is still triggering an issue:
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
KASAN: stack-out-of-bounds Read in getname_kernel
BTRFS info (device loop0): disabling free space tree
BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE (0x1) BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE_VALID (0x2)
==================================================================
BUG: KASAN: stack-out-of-bounds in strlen+0x58/0x70 lib/string.c:418 Read of size 1 at addr ffffc9000519fe08 by task syz-executor.0/5479 CPU: 1 PID: 5479 Comm: syz-executor.0 Not tainted 6.7.0-rc5-syzkaller-00200-g3bd7d7488169-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:364 [inline] print_report+0x163/0x540 mm/kasan/report.c:475 kasan_report+0x142/0x170 mm/kasan/report.c:588 strlen+0x58/0x70 lib/string.c:418 getname_kernel+0x1d/0x2e0 fs/namei.c:226 kern_path+0x1d/0x50 fs/namei.c:2609 lookup_bdev block/bdev.c:979 [inline] bdev_open_by_path+0xd1/0x540 block/bdev.c:901 btrfs_init_dev_replace_tgtdev fs/btrfs/dev-replace.c:260 [inline] btrfs_dev_replace_start fs/btrfs/dev-replace.c:638 [inline] btrfs_dev_replace_by_ioctl+0x41b/0x2010 fs/btrfs/dev-replace.c:748 btrfs_ioctl_dev_replace+0x3c9/0x4a0 fs/btrfs/ioctl.c:3298 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f412127cba9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f4121f980c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f412139bf80 RCX: 00007f412127cba9 RDX: 0000000020000540 RSI: 00000000ca289435 RDI: 0000000000000005 RBP: 00007f41212c847a R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007f412139bf80 R15: 00007ffcdd6baae8 </TASK> The buggy address belongs to stack of task syz-executor.0/5479 and is located at offset 2632 in frame: btrfs_ioctl_dev_replace+0x0/0x4a0 fs/btrfs/ioctl.c:3931
This frame has 1 object:
[32, 2632) 'p'
The buggy address belongs to the virtual mapping at [ffffc90005198000, ffffc900051a1000) created by: copy_process+0x5d1/0x3fb0 kernel/fork.c:2332 The buggy address belongs to the physical page:
page:ffffea00007149c0 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1c527 memcg:ffff88801e905a82
flags: 0xfff00000000000(node=0|zone=1|lastcpupid=0x7ff)page_type: 0xffffffff()
raw: 00fff00000000000 0000000000000000 dead000000000122 0000000000000000
raw: 0000000000000000 0000000000000000 00000001ffffffff ffff88801e905a82
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x102dc2(GFP_HIGHUSER|__GFP_NOWARN|__GFP_ZERO), pid 5449, tgid 5449 (dhcpcd-run-hook), ts 81588018886, free_ts 81585719939
set_page_owner include/linux/page_owner.h:31 [inline]
post_alloc_hook+0x1e6/0x210 mm/page_alloc.c:1537
prep_new_page mm/page_alloc.c:1544 [inline]
get_page_from_freelist+0x33ea/0x3570 mm/page_alloc.c:3312
__alloc_pages+0x255/0x680 mm/page_alloc.c:4568
alloc_pages_mpol+0x3de/0x640 mm/mempolicy.c:2133
vm_area_alloc_pages mm/vmalloc.c:3063 [inline]
__vmalloc_area_node mm/vmalloc.c:3139 [inline]
__vmalloc_node_range+0x9a3/0x14a0 mm/vmalloc.c:3320
alloc_thread_stack_node kernel/fork.c:309 [inline]
dup_task_struct+0x3e5/0x7d0 kernel/fork.c:1118
copy_process+0x5d1/0x3fb0 kernel/fork.c:2332
kernel_clone+0x222/0x840 kernel/fork.c:2907
__do_sys_clone kernel/fork.c:3050 [inline]
__se_sys_clone kernel/fork.c:3034 [inline]
__x64_sys_clone+0x258/0x2a0 kernel/fork.c:3034
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x63/0x6b
page last free stack trace:
reset_page_owner include/linux/page_owner.h:24 [inline]
free_pages_prepare mm/page_alloc.c:1137 [inline]
free_unref_page_prepare+0x931/0xa60 mm/page_alloc.c:2347
free_unref_page_list+0x5a0/0x840 mm/page_alloc.c:2533
release_pages+0x2117/0x2400 mm/swap.c:1042
tlb_batch_pages_flush mm/mmu_gather.c:98 [inline]
tlb_flush_mmu_free mm/mmu_gather.c:293 [inline]
tlb_flush_mmu+0x34c/0x4e0 mm/mmu_gather.c:300
tlb_finish_mmu+0xd4/0x1f0 mm/mmu_gather.c:392
exit_mmap+0x4d3/0xc60 mm/mmap.c:3321
__mmput+0x115/0x3c0 kernel/fork.c:1349
exit_mm+0x21f/0x300 kernel/exit.c:567
do_exit+0x9b7/0x2750 kernel/exit.c:858
do_group_exit+0x206/0x2c0 kernel/exit.c:1021
__do_sys_exit_group kernel/exit.c:1032 [inline]
__se_sys_exit_group kernel/exit.c:1030 [inline]
__x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1030
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x63/0x6b
Memory state around the buggy address:
ffffc9000519fd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffffc9000519fd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffffc9000519fe00: 00 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3
^
ffffc9000519fe80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
ffffc9000519ff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
==================================================================Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git console output: https://syzkaller.appspot.com/x/log.txt?x=1753a73ee80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=13fde369e80000
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
fs/btrfs/dev-replace.c +2 -1
@@ -741,7 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, }if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + args->start.tgtdev_name[0 ] ==0 )return -EINVAL ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,
fs/btrfs/ioctl.c +1 -1
@@ -3283,7 +3283,7 @@ static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info,return -EINVAL ; } - p =memdup_user (arg,sizeof (*p)); + p =memdup_user (arg,17 );if (IS_ERR (p))return PTR_ERR (p);
mm/util.c +1 -1
@@ -194,7 +194,7 @@ void *memdup_user(const void __user *src, size_t len) {void *p; - p =kmalloc_track_caller (len,GFP_USER | __GFP_NOWARN); + p =kmalloc_track_caller (len,GFP_USER | __GFP_NOWARN | __GFP_ZERO);if (!p)return ERR_PTR (-ENOMEM );
syzbot
syzbotsyzbot has tested the proposed patch but the reproducer is still triggering an issue:
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
KASAN: slab-out-of-bounds Read in btrfs_dev_replace_by_ioctl
BTRFS info (device loop0): disabling free space tree
BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE (0x1) BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE_VALID (0x2)
==================================================================
BUG: KASAN: slab-out-of-bounds in btrfs_dev_replace_by_ioctl+0xb6/0x2010 fs/btrfs/dev-replace.c:735 Read of size 8 at addr ffff8880239268d8 by task syz-executor.0/5475 CPU: 1 PID: 5475 Comm: syz-executor.0 Not tainted 6.7.0-rc5-syzkaller-00200-g3bd7d7488169-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:364 [inline] print_report+0x163/0x540 mm/kasan/report.c:475 kasan_report+0x142/0x170 mm/kasan/report.c:588 btrfs_dev_replace_by_ioctl+0xb6/0x2010 fs/btrfs/dev-replace.c:735 btrfs_ioctl_dev_replace+0x2c9/0x390 fs/btrfs/ioctl.c:3299 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7ff58447cba9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ff5852580c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007ff58459bf80 RCX: 00007ff58447cba9 RDX: 0000000020000540 RSI: 00000000ca289435 RDI: 0000000000000005 RBP: 00007ff5844c847a R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007ff58459bf80 R15: 00007fff749803c8 </TASK> Allocated by task 5475: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4f/0x70 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:374 [inline] __kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:383 kasan_kmalloc include/linux/kasan.h:198 [inline] __do_kmalloc_node mm/slab_common.c:1007 [inline] __kmalloc_node_track_caller+0xb1/0x190 mm/slab_common.c:1027 memdup_user+0x2b/0xc0 mm/util.c:197 btrfs_ioctl_dev_replace+0xb8/0x390 fs/btrfs/ioctl.c:3286 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b The buggy address belongs to the object at ffff8880239268c0 which belongs to the cache kmalloc-32 of size 32
The buggy address is located 7 bytes to the right of
allocated 17-byte region [ffff8880239268c0, ffff8880239268d1)
The buggy address belongs to the physical page:
page:ffffea00008e4980 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x23926
flags: 0xfff00000000800(slab|node=0|zone=1|lastcpupid=0x7ff)
page_type: 0xffffffff()
raw: 00fff00000000800 ffff888012c41500 ffffea000099dd40 dead000000000002
raw: 0000000000000000 0000000080400040 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x12cc0(GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY), pid 1, tgid 1 (swapper/0), ts 11104550106, free_ts 11081252843
set_page_owner include/linux/page_owner.h:31 [inline]
post_alloc_hook+0x1e6/0x210 mm/page_alloc.c:1537
prep_new_page mm/page_alloc.c:1544 [inline]
get_page_from_freelist+0x33ea/0x3570 mm/page_alloc.c:3312
__alloc_pages+0x255/0x680 mm/page_alloc.c:4568
alloc_pages_mpol+0x3de/0x640 mm/mempolicy.c:2133
alloc_slab_page+0x6a/0x170 mm/slub.c:1870
allocate_slab mm/slub.c:2017 [inline]
new_slab+0x84/0x2f0 mm/slub.c:2070
___slab_alloc+0xc8a/0x1330 mm/slub.c:3223
__slab_alloc mm/slub.c:3322 [inline]
__slab_alloc_node mm/slub.c:3375 [inline]
slab_alloc_node mm/slub.c:3468 [inline]
__kmem_cache_alloc_node+0x21d/0x300 mm/slub.c:3517
__do_kmalloc_node mm/slab_common.c:1006 [inline]
__kmalloc_node_track_caller+0xa0/0x190 mm/slab_common.c:1027
kvasprintf+0xdf/0x190 lib/kasprintf.c:25
__kthread_create_on_node+0x1a9/0x3c0 kernel/kthread.c:444
kthread_create_on_node+0xde/0x120 kernel/kthread.c:512
vivid_create_instance drivers/media/test-drivers/vivid/vivid-core.c:1927 [inline]
vivid_probe+0x5422/0x6fa0 drivers/media/test-drivers/vivid/vivid-core.c:2004
platform_probe+0x135/0x1b0 drivers/base/platform.c:1404
really_probe+0x294/0xc30 drivers/base/dd.c:658
__driver_probe_device+0x1a2/0x3d0 drivers/base/dd.c:800
page last free stack trace:
reset_page_owner include/linux/page_owner.h:24 [inline]
free_pages_prepare mm/page_alloc.c:1137 [inline]
free_unref_page_prepare+0x931/0xa60 mm/page_alloc.c:2347
free_unref_page+0x37/0x3f0 mm/page_alloc.c:2487
mm_free_pgd kernel/fork.c:803 [inline]
__mmdrop+0xb8/0x3d0 kernel/fork.c:919
free_bprm+0x144/0x330 fs/exec.c:1490
kernel_execve+0x8f7/0xa20 fs/exec.c:2024
call_usermodehelper_exec_async+0x233/0x370 kernel/umh.c:110
ret_from_fork+0x48/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:242
Memory state around the buggy address:
ffff888023926780: 00 00 00 00 fc fc fc fc 00 00 00 00 fc fc fc fc
ffff888023926800: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
>ffff888023926880: fb fb fb fb fc fc fc fc 00 00 01 fc fc fc fc fc
^
ffff888023926900: 00 00 03 fc fc fc fc fc 00 00 00 fc fc fc fc fc
ffff888023926980: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
==================================================================Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git console output: https://syzkaller.appspot.com/x/log.txt?x=12a3149ee80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=12152276e80000
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
fs/btrfs/dev-replace.c +2 -1
@@ -741,7 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, }if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + args->start.tgtdev_name[0 ] ==0 )return -EINVAL ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,
fs/btrfs/ioctl.c +1 -1
@@ -3283,7 +3283,7 @@ static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info,return -EINVAL ; } - p =memdup_user (arg,sizeof (*p)); + p =memdup_user (arg,1042 );if (IS_ERR (p))return PTR_ERR (p);
mm/util.c +1 -1
@@ -194,7 +194,7 @@ void *memdup_user(const void __user *src, size_t len) {void *p; - p =kmalloc_track_caller (len,GFP_USER | __GFP_NOWARN); + p =kmalloc_track_caller (len,GFP_USER | __GFP_NOWARN | __GFP_ZERO);if (!p)return ERR_PTR (-ENOMEM );
syzbot
syzbotsyzbot has tested the proposed patch but the reproducer is still triggering an issue:
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
KASAN: slab-out-of-bounds Read in btrfs_dev_replace_by_ioctl
BTRFS info (device loop0): disabling free space tree
BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE (0x1) BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE_VALID (0x2)
==================================================================
BUG: KASAN: slab-out-of-bounds in btrfs_dev_replace_by_ioctl+0x1dc5/0x2010 fs/btrfs/dev-replace.c:744 Read of size 1 at addr ffff888021b2a421 by task syz-executor.0/5480 CPU: 1 PID: 5480 Comm: syz-executor.0 Not tainted 6.7.0-rc5-syzkaller-00200-g3bd7d7488169-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:364 [inline] print_report+0x163/0x540 mm/kasan/report.c:475 kasan_report+0x142/0x170 mm/kasan/report.c:588 btrfs_dev_replace_by_ioctl+0x1dc5/0x2010 fs/btrfs/dev-replace.c:744 btrfs_ioctl_dev_replace+0x2c9/0x390 fs/btrfs/ioctl.c:3299 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f695d67cba9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f695e45a0c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f695d79bf80 RCX: 00007f695d67cba9 RDX: 0000000020000540 RSI: 00000000ca289435 RDI: 0000000000000005 RBP: 00007f695d6c847a R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007f695d79bf80 R15: 00007ffe9e2e6458 </TASK> Allocated by task 5480: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4f/0x70 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:374 [inline] __kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:383 kasan_kmalloc include/linux/kasan.h:198 [inline] __do_kmalloc_node mm/slab_common.c:1007 [inline] __kmalloc_node_track_caller+0xb1/0x190 mm/slab_common.c:1027 memdup_user+0x2b/0xc0 mm/util.c:197 btrfs_ioctl_dev_replace+0xb8/0x390 fs/btrfs/ioctl.c:3286 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b The buggy address belongs to the object at ffff888021b2a000 which belongs to the cache kmalloc-2k of size 2048
The buggy address is located 15 bytes to the right of
allocated 1042-byte region [ffff888021b2a000, ffff888021b2a412)
The buggy address belongs to the physical page:
page:ffffea000086ca00 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x21b28 head:ffffea000086ca00 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0xfff00000000840(slab|head|node=0|zone=1|lastcpupid=0x7ff)page_type: 0xffffffff()
raw: 00fff00000000840 ffff888012c42000 dead000000000122 0000000000000000
raw: 0000000000000000 0000000080080008 00000001ffffffff 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 0x1d20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC|__GFP_HARDWALL), pid 4502, tgid 4502 (klogd), ts 85479727402, free_ts 85422702099
set_page_owner include/linux/page_owner.h:31 [inline]
post_alloc_hook+0x1e6/0x210 mm/page_alloc.c:1537
prep_new_page mm/page_alloc.c:1544 [inline]
get_page_from_freelist+0x33ea/0x3570 mm/page_alloc.c:3312
__alloc_pages+0x255/0x680 mm/page_alloc.c:4568
alloc_pages_mpol+0x3de/0x640 mm/mempolicy.c:2133
alloc_slab_page+0x6a/0x170 mm/slub.c:1870
allocate_slab mm/slub.c:2017 [inline]
new_slab+0x84/0x2f0 mm/slub.c:2070
___slab_alloc+0xc8a/0x1330 mm/slub.c:3223
__slab_alloc mm/slub.c:3322 [inline]
__slab_alloc_node mm/slub.c:3375 [inline]
slab_alloc_node mm/slub.c:3468 [inline]
__kmem_cache_alloc_node+0x21d/0x300 mm/slub.c:3517
kmalloc_trace+0x2a/0x60 mm/slab_common.c:1098
kmalloc include/linux/slab.h:600 [inline]
syslog_print+0x121/0x9b0 kernel/printk/printk.c:1550
do_syslog+0x505/0x890 kernel/printk/printk.c:1728
__do_sys_syslog kernel/printk/printk.c:1820 [inline]
__se_sys_syslog kernel/printk/printk.c:1818 [inline]
__x64_sys_syslog+0x7c/0x90 kernel/printk/printk.c:1818
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x63/0x6b
page last free stack trace:
reset_page_owner include/linux/page_owner.h:24 [inline]
free_pages_prepare mm/page_alloc.c:1137 [inline]
free_unref_page_prepare+0x931/0xa60 mm/page_alloc.c:2347
free_unref_page+0x37/0x3f0 mm/page_alloc.c:2487
discard_slab mm/slub.c:2116 [inline]
__unfreeze_partials+0x1e0/0x220 mm/slub.c:2655
put_cpu_partial+0x17b/0x250 mm/slub.c:2731
__slab_free+0x2b6/0x390 mm/slub.c:3679
qlink_free mm/kasan/quarantine.c:168 [inline]
qlist_free_all+0x75/0xe0 mm/kasan/quarantine.c:187
kasan_quarantine_reduce+0x14b/0x160 mm/kasan/quarantine.c:294
__kasan_slab_alloc+0x23/0x70 mm/kasan/common.c:305
kasan_slab_alloc include/linux/kasan.h:188 [inline]
slab_post_alloc_hook+0x6c/0x3c0 mm/slab.h:763
slab_alloc_node mm/slub.c:3478 [inline]
slab_alloc mm/slub.c:3486 [inline]
__kmem_cache_alloc_lru mm/slub.c:3493 [inline]
kmem_cache_alloc+0x19e/0x2b0 mm/slub.c:3502
alloc_reserved_tree_block fs/btrfs/extent-tree.c:4876 [inline]
run_delayed_tree_ref fs/btrfs/extent-tree.c:1765 [inline]
run_one_delayed_ref fs/btrfs/extent-tree.c:1799 [inline]
btrfs_run_delayed_refs_for_head fs/btrfs/extent-tree.c:2064 [inline]
__btrfs_run_delayed_refs+0x14af/0x46c0 fs/btrfs/extent-tree.c:2134
btrfs_run_delayed_refs+0x188/0x2c0 fs/btrfs/extent-tree.c:2246
commit_cowonly_roots+0x66b/0x860 fs/btrfs/transaction.c:1416
btrfs_commit_transaction+0xff5/0x3740 fs/btrfs/transaction.c:2485
btrfs_rebuild_free_space_tree+0x1de/0x370 fs/btrfs/free-space-tree.c:1344
btrfs_start_pre_rw_mount+0xef3/0x1340 fs/btrfs/disk-io.c:2965
Memory state around the buggy address:
ffff888021b2a300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff888021b2a380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff888021b2a400: 00 00 02 fc fc fc fc fc fc fc fc fc fc fc fc fc
^
ffff888021b2a480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff888021b2a500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git console output: https://syzkaller.appspot.com/x/log.txt?x=16b1a6c6e80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=100aa8d6e80000
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
mm/util.c +1 -1
@@ -194,7 +194,7 @@ void *memdup_user(const void __user *src, size_t len) {void *p; - p =kmalloc_track_caller (len,GFP_USER | __GFP_NOWARN); + p =kmalloc_track_caller (len,GFP_USER | __GFP_NOWARN | __GFP_ZERO);if (!p)return ERR_PTR (-ENOMEM );
fs/btrfs/dev-replace.c +5 -2
@@ -730,7 +730,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,int btrfs_dev_replace_by_ioctl (struct btrfs_fs_info *fs_info,struct btrfs_ioctl_dev_replace_args *args) { -int ret; +int ret, len;switch (args->start.cont_reading_from_srcdev_mode) {case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS :
@@ -740,8 +740,11 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,return -EINVAL ; } + len =strnlen (args->start.tgtdev_name,BTRFS_DEVICE_PATH_NAME_MAX +1 ); +printk ("l: %d, >%s<, %s\n" , len, args->start.tgtdev_name, __func__);if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + len ==BTRFS_DEVICE_PATH_NAME_MAX +1 )return -EINVAL ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,
syzbot
syzbotsyzbot has tested the proposed patch but the reproducer is still triggering an issue:
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
KASAN: slab-out-of-bounds Read in btrfs_dev_replace_by_ioctl
BTRFS info (device loop0): disabling free space tree
BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE (0x1) BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE_VALID (0x2)
==================================================================
BUG: KASAN: slab-out-of-bounds in string_nocheck lib/vsprintf.c:646 [inline] BUG: KASAN: slab-out-of-bounds in string+0x218/0x2b0 lib/vsprintf.c:728 Read of size 1 at addr ffff88807bb70a28 by task syz-executor.0/5482 CPU: 0 PID: 5482 Comm: syz-executor.0 Not tainted 6.7.0-rc5-syzkaller-00200-g3bd7d7488169-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:364 [inline] print_report+0x163/0x540 mm/kasan/report.c:475 kasan_report+0x142/0x170 mm/kasan/report.c:588 string_nocheck lib/vsprintf.c:646 [inline] string+0x218/0x2b0 lib/vsprintf.c:728 vsnprintf+0x1101/0x1da0 lib/vsprintf.c:2819 vprintk_store+0x47f/0x1160 kernel/printk/printk.c:2187 vprintk_emit+0x119/0x720 kernel/printk/printk.c:2284 _printk+0xd5/0x120 kernel/printk/printk.c:2328 btrfs_dev_replace_by_ioctl+0x16e/0x2020 fs/btrfs/dev-replace.c:744 btrfs_ioctl_dev_replace+0x2c9/0x390 fs/btrfs/ioctl.c:3299 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f9e6107cba9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f9e61de30c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f9e6119bf80 RCX: 00007f9e6107cba9 RDX: 0000000020000540 RSI: 00000000ca289435 RDI: 0000000000000005 RBP: 00007f9e610c847a R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007f9e6119bf80 R15: 00007fffc9000478 </TASK> Allocated by task 5482: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4f/0x70 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:374 [inline] __kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:383 kasan_kmalloc include/linux/kasan.h:198 [inline] __do_kmalloc_node mm/slab_common.c:1007 [inline] __kmalloc_node_track_caller+0xb1/0x190 mm/slab_common.c:1027 memdup_user+0x2b/0xc0 mm/util.c:197 btrfs_ioctl_dev_replace+0xb8/0x390 fs/btrfs/ioctl.c:3286 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b The buggy address belongs to the object at ffff88807bb70000 which belongs to the cache kmalloc-4k of size 4096
The buggy address is located 0 bytes to the right of
allocated 2600-byte region [ffff88807bb70000, ffff88807bb70a28)
The buggy address belongs to the physical page:
page:ffffea0001eedc00 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x7bb70 head:ffffea0001eedc00 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0xfff00000000840(slab|head|node=0|zone=1|lastcpupid=0x7ff)page_type: 0xffffffff()
raw: 00fff00000000840 ffff888012c42140 dead000000000122 0000000000000000
raw: 0000000000000000 0000000080040004 00000001ffffffff 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 0x1d20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC|__GFP_HARDWALL), pid 5482, tgid 5481 (syz-executor.0), ts 83591699256, free_ts 83563781743
set_page_owner include/linux/page_owner.h:31 [inline]
post_alloc_hook+0x1e6/0x210 mm/page_alloc.c:1537
prep_new_page mm/page_alloc.c:1544 [inline]
get_page_from_freelist+0x33ea/0x3570 mm/page_alloc.c:3312
__alloc_pages+0x255/0x680 mm/page_alloc.c:4568
alloc_pages_mpol+0x3de/0x640 mm/mempolicy.c:2133
alloc_slab_page+0x6a/0x170 mm/slub.c:1870
allocate_slab mm/slub.c:2017 [inline]
new_slab+0x84/0x2f0 mm/slub.c:2070
___slab_alloc+0xc8a/0x1330 mm/slub.c:3223
__slab_alloc mm/slub.c:3322 [inline]
__slab_alloc_node mm/slub.c:3375 [inline]
slab_alloc_node mm/slub.c:3468 [inline]
__kmem_cache_alloc_node+0x21d/0x300 mm/slub.c:3517
__do_kmalloc_node mm/slab_common.c:1006 [inline]
__kmalloc_node_track_caller+0xa0/0x190 mm/slab_common.c:1027
memdup_user+0x2b/0xc0 mm/util.c:197
btrfs_ioctl_dev_replace+0xb8/0x390 fs/btrfs/ioctl.c:3286
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x63/0x6b
page last free stack trace:
reset_page_owner include/linux/page_owner.h:24 [inline]
free_pages_prepare mm/page_alloc.c:1137 [inline]
free_unref_page_prepare+0x931/0xa60 mm/page_alloc.c:2347
free_unref_page+0x37/0x3f0 mm/page_alloc.c:2487
discard_slab mm/slub.c:2116 [inline]
__unfreeze_partials+0x1e0/0x220 mm/slub.c:2655
put_cpu_partial+0x17b/0x250 mm/slub.c:2731
__slab_free+0x2b6/0x390 mm/slub.c:3679
qlink_free mm/kasan/quarantine.c:168 [inline]
qlist_free_all+0x75/0xe0 mm/kasan/quarantine.c:187
kasan_quarantine_reduce+0x14b/0x160 mm/kasan/quarantine.c:294
__kasan_slab_alloc+0x23/0x70 mm/kasan/common.c:305
kasan_slab_alloc include/linux/kasan.h:188 [inline]
slab_post_alloc_hook+0x6c/0x3c0 mm/slab.h:763
slab_alloc_node mm/slub.c:3478 [inline]
slab_alloc mm/slub.c:3486 [inline]
__kmem_cache_alloc_lru mm/slub.c:3493 [inline]
kmem_cache_alloc+0x19e/0x2b0 mm/slub.c:3502
anon_vma_chain_alloc mm/rmap.c:142 [inline]
__anon_vma_prepare+0x68/0x410 mm/rmap.c:196
vmf_anon_prepare mm/memory.c:3072 [inline]
do_cow_fault mm/memory.c:4648 [inline]
do_fault mm/memory.c:4765 [inline]
do_pte_missing mm/memory.c:3731 [inline]
handle_pte_fault mm/memory.c:5039 [inline]
__handle_mm_fault mm/memory.c:5180 [inline]
handle_mm_fault+0x5516/0x6680 mm/memory.c:5345
do_user_addr_fault arch/x86/mm/fault.c:1413 [inline]
handle_page_fault arch/x86/mm/fault.c:1505 [inline]
exc_page_fault+0x2ad/0x870 arch/x86/mm/fault.c:1561
asm_exc_page_fault+0x26/0x30 arch/x86/include/asm/idtentry.h:570
Memory state around the buggy address:
ffff88807bb70900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88807bb70980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88807bb70a00: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
^
ffff88807bb70a80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88807bb70b00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git console output: https://syzkaller.appspot.com/x/log.txt?x=104f2daee80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=148e8d01e80000
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
mm/util.c +1 -1
@@ -194,7 +194,7 @@ void *memdup_user(const void __user *src, size_t len) {void *p; - p =kmalloc_track_caller (len,GFP_USER | __GFP_NOWARN); + p =kmalloc_track_caller (len,GFP_USER | __GFP_NOWARN | __GFP_ZERO);if (!p)return ERR_PTR (-ENOMEM );
fs/btrfs/dev-replace.c +5 -2
@@ -730,7 +730,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,int btrfs_dev_replace_by_ioctl (struct btrfs_fs_info *fs_info,struct btrfs_ioctl_dev_replace_args *args) { -int ret; +int ret, len;switch (args->start.cont_reading_from_srcdev_mode) {case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS :
@@ -740,8 +740,11 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,return -EINVAL ; } + len =strnlen (args->start.tgtdev_name,BTRFS_DEVICE_PATH_NAME_MAX +1 ); +printk ("l: %d, %s\n" , len, __func__);if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + len ==BTRFS_DEVICE_PATH_NAME_MAX +1 )return -EINVAL ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,
syzbot
syzbotsyzbot has tested the proposed patch and the reproducer did not trigger any issue:
Hello,
syzbot has tested the proposed patch and the reproducer did not trigger any issue:
Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git console output: https://syzkaller.appspot.com/x/log.txt?x=1013149ee80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=109c16d6e80000
Note: testing is done by a robot and is best-effort only.
PATCH 1/1 btrfs: fix oob Read in getname_kernel
In reply to syzbotIf ioctl does not pass in the correct tgtdev_name string, oob will occur because "\0" cannot be found.
--- fs/btrfs/dev-replace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/btrfs/dev-replace.c +4 -2
@@ -730,7 +730,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,int btrfs_dev_replace_by_ioctl (struct btrfs_fs_info *fs_info,struct btrfs_ioctl_dev_replace_args *args) { -int ret; +int ret, len;switch (args->start.cont_reading_from_srcdev_mode) {case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS :
@@ -740,8 +740,10 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,return -EINVAL ; } + len =strnlen (args->start.tgtdev_name,BTRFS_DEVICE_PATH_NAME_MAX +1 );if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + len ==BTRFS_DEVICE_PATH_NAME_MAX +1 )return -EINVAL ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,
Signature · 1 line
2.43.0
Re: [PATCH] btrfs: fix oob Read in getname_kernel
Quoted 23 lines · Edward Adam Davis
If ioctl does not pass in the correct
tgtdev_namestring, oob will occur because "\0" cannot be found.Reported-and-tested-by [email protected]Signed-off-by Edward Adam Davis <[email protected]>--- fs/btrfs/dev-replace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)fs/btrfs/dev-replace.c +1
-1@@ -730,7 +730,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,int btrfs_dev_replace_by_ioctl (struct btrfs_fs_info *fs_info,struct btrfs_ioctl_dev_replace_args *args) { -int ret; +int ret, len;switch (args->start.cont_reading_from_srcdev_mode) {case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS :
fs/btrfs/dev-replace.c int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, · line 746
Quoted 8 lines
fs/btrfs/dev-replace.c +3
-1@@ -740,8 +740,10 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,return -EINVAL ; } + len =strnlen (args->start.tgtdev_name,BTRFS_DEVICE_PATH_NAME_MAX +1 );if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + len ==BTRFS_DEVICE_PATH_NAME_MAX +1 )
I think srcdev_name would have to be checked the same way, but instead of strnlen I'd do memchr(name, 0, BTRFS_DEVICE_PATH_NAME_MAX). The check for 0 in [0] is probably pointless, it's just a shortcut for an empty buffer. We expect a valid 0-terminated string, which could be an invalid path but that will be found out later when opening the block device.
Re: [PATCH] btrfs: fix oob Read in getname_kernel
Quoted 27 lines · David Sterba
Quoted 26 lines · Edward Adam Davis
If ioctl does not pass in the correct
tgtdev_namestring, oob will occur because "\0" cannot be found.Reported-and-tested-by [email protected]Signed-off-by Edward Adam Davis <[email protected]>--- fs/btrfs/dev-replace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)fs/btrfs/dev-replace.c +1
-1@@ -730,7 +730,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,int btrfs_dev_replace_by_ioctl (struct btrfs_fs_info *fs_info,struct btrfs_ioctl_dev_replace_args *args) { -int ret; +int ret, len;switch (args->start.cont_reading_from_srcdev_mode) {case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS :@@ -740,8 +740,10 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,return -EINVAL ; }
Quoted 11 lines
fs/btrfs/dev-replace.c int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, · line 746
Quoted 5 lines
fs/btrfs/dev-replace.c +3
-1+ len =strnlen (args->start.tgtdev_name,BTRFS_DEVICE_PATH_NAME_MAX +1 );if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + len ==BTRFS_DEVICE_PATH_NAME_MAX +1 )I think
srcdev_namewould have to be checked the same way, but instead of strnlen I'd domemchr(name, 0, BTRFS_DEVICE_PATH_NAME_MAX). The check for 0 in [0] is probably pointless, it's just a shortcut for an empty buffer. We expect a valid 0-terminated string, which could be an invalid path but that will be found out later when opening the block device.
Please let me know if you're going to send an updated fix. I'd like to get this fixed to close the syzbot report but also want to give you the credit for debugging and fix.
The preferred fix is something like that:
fs/btrfs/dev-replace.c +2 -0
@@ -741,6 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || args->start.tgtdev_name[0 ] =='\0' )return -EINVAL ; + args->start.srcdev_name[BTRFS_PATH_NAME_MAX ] =0 ; + args->start.tgtdev_name[BTRFS_PATH_NAME_MAX ] =0 ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name, args->start.srcdevid,
Quoted 47 lines · David Sterba
Quoted 26 lines
Quoted 26 lines
If ioctl does not pass in the correct
tgtdev_namestring, oob will occur because "\0" cannot be found.Reported-and-tested-by [email protected]Signed-off-by Edward Adam Davis <[email protected]>--- fs/btrfs/dev-replace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)fs/btrfs/dev-replace.c +1
-1@@ -730,7 +730,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,int btrfs_dev_replace_by_ioctl (struct btrfs_fs_info *fs_info,struct btrfs_ioctl_dev_replace_args *args) { -int ret; +int ret, len;switch (args->start.cont_reading_from_srcdev_mode) {case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS :@@ -740,8 +740,10 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,return -EINVAL ; }Quoted 11 lines
fs/btrfs/dev-replace.c int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, · line 746
Quoted 5 lines
fs/btrfs/dev-replace.c +3
-1+ len =strnlen (args->start.tgtdev_name,BTRFS_DEVICE_PATH_NAME_MAX +1 );if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + len ==BTRFS_DEVICE_PATH_NAME_MAX +1 )I think
srcdev_namewould have to be checked the same way, but instead of strnlen I'd domemchr(name, 0, BTRFS_DEVICE_PATH_NAME_MAX). The check for 0 in [0] is probably pointless, it's just a shortcut for an empty buffer. We expect a valid 0-terminated string, which could be an invalid path but that will be found out later when opening the block device.Please let me know if you're going to send an updated fix. I'd like to get this fixed to close the syzbot report but also want to give you the credit for debugging and fix.
The preferred fix is something like that:
fs/btrfs/dev-replace.c int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, · line 745
Quoted 5 lines
fs/btrfs/dev-replace.c +2
-0@@ -741,6 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || args->start.tgtdev_name[0 ] =='\0' )return -EINVAL ; + args->start.srcdev_name[BTRFS_PATH_NAME_MAX ] =0 ; + args->start.tgtdev_name[BTRFS_PATH_NAME_MAX ] =0 ;
This is not correct,
1. The maximum length of tgtdev_name is BTRFS_DEVICE_PATH_NAME_MAX + 1
2. strnlen should be used to confirm the presence of \0 in tgtdev_name
3. Input values should not be subjectively updated
4. The current issue only involves tgtdev_name
Quoted 3 lines
fs/btrfs/dev-replace.c +0
-0ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name, args->start.srcdevid,
Quoted 45 lines · Edward Adam Davis
Quoted 44 lines · David Sterba
Quoted 26 lines
Quoted 26 lines
If ioctl does not pass in the correct
tgtdev_namestring, oob will occur because "\0" cannot be found.Reported-and-tested-by [email protected]Signed-off-by Edward Adam Davis <[email protected]>--- fs/btrfs/dev-replace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)fs/btrfs/dev-replace.c +1
-1@@ -730,7 +730,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,int btrfs_dev_replace_by_ioctl (struct btrfs_fs_info *fs_info,struct btrfs_ioctl_dev_replace_args *args) { -int ret; +int ret, len;switch (args->start.cont_reading_from_srcdev_mode) {case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS :@@ -740,8 +740,10 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,return -EINVAL ; }Quoted 11 lines
fs/btrfs/dev-replace.c int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, · line 746
Quoted 5 lines
fs/btrfs/dev-replace.c +3
-1+ len =strnlen (args->start.tgtdev_name,BTRFS_DEVICE_PATH_NAME_MAX +1 );if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + len ==BTRFS_DEVICE_PATH_NAME_MAX +1 )I think
srcdev_namewould have to be checked the same way, but instead of strnlen I'd domemchr(name, 0, BTRFS_DEVICE_PATH_NAME_MAX). The check for 0 in [0] is probably pointless, it's just a shortcut for an empty buffer. We expect a valid 0-terminated string, which could be an invalid path but that will be found out later when opening the block device.Please let me know if you're going to send an updated fix. I'd like to get this fixed to close the syzbot report but also want to give you the credit for debugging and fix.
The preferred fix is something like that:
Quoted 10 lines
fs/btrfs/dev-replace.c int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, · line 745
Quoted 8 lines
fs/btrfs/dev-replace.c +2
-0@@ -741,6 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || args->start.tgtdev_name[0 ] =='\0' )return -EINVAL ; + args->start.srcdev_name[BTRFS_PATH_NAME_MAX ] =0 ; + args->start.tgtdev_name[BTRFS_PATH_NAME_MAX ] =0 ;This is not correct,
1. The maximum length oftgtdev_nameisBTRFS_DEVICE_PATH_NAME_MAX+ 1
Yes, so if the array size is N + 1 then writing to offset N is valid. It's a bit confusing that the paths using BTRFS_PATH_NAME_MAX are +1 bigger so it's not folling the patterns using N as the limit.
Quoted 1 line
2. strnlen should be used to confirm the presence of \0 in
tgtdev_name
Yes, this would work, with the slight difference that memchr looks for the 0 character regardless of any other, while strnlen also looks for any intermediate 0. memchr is an optimization, for input parameter validation it does not matter.
Quoted 1 line
3. Input values should not be subjectively updated
Yeah, this is indeed subjective, I propsed that because we already do that for subvolume ioctls. This probably would never show up in practice, the paths are not that long and even if the real linux limit is PATH_MAX (4096) and BTRFS_PATH_NAME_MAX was originally set to a lower value it's still enough for everybody.
From practiacal perspective I don't see any difference between overwriting the last place of NUL or checking it by strnlen/memchr.
Quoted 1 line
4. The current issue only involves
tgtdev_name
Right, that needs to be fixed. With bugs like that it's always good to look around for similar cases or audit everything of similar pattern, here it's an ioctl taking a user-specified path. If the target path is fixed, we need the source path fixed too. It can be a separate patch, no problem.
Quoted 45 lines · Edward Adam Davis
Quoted 44 lines · David Sterba
Quoted 26 lines
Quoted 26 lines
If ioctl does not pass in the correct
tgtdev_namestring, oob will occur because "\0" cannot be found.Reported-and-tested-by [email protected]Signed-off-by Edward Adam Davis <[email protected]>--- fs/btrfs/dev-replace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)fs/btrfs/dev-replace.c +1
-1@@ -730,7 +730,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,int btrfs_dev_replace_by_ioctl (struct btrfs_fs_info *fs_info,struct btrfs_ioctl_dev_replace_args *args) { -int ret; +int ret, len;switch (args->start.cont_reading_from_srcdev_mode) {case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS :@@ -740,8 +740,10 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,return -EINVAL ; }Quoted 11 lines
fs/btrfs/dev-replace.c int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, · line 746
Quoted 5 lines
fs/btrfs/dev-replace.c +3
-1+ len =strnlen (args->start.tgtdev_name,BTRFS_DEVICE_PATH_NAME_MAX +1 );if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || - args->start.tgtdev_name[0 ] =='\0' ) + args->start.tgtdev_name[0 ] =='\0' || + len ==BTRFS_DEVICE_PATH_NAME_MAX +1 )I think
srcdev_namewould have to be checked the same way, but instead of strnlen I'd domemchr(name, 0, BTRFS_DEVICE_PATH_NAME_MAX). The check for 0 in [0] is probably pointless, it's just a shortcut for an empty buffer. We expect a valid 0-terminated string, which could be an invalid path but that will be found out later when opening the block device.Please let me know if you're going to send an updated fix. I'd like to get this fixed to close the syzbot report but also want to give you the credit for debugging and fix.
The preferred fix is something like that:
Quoted 12 lines
fs/btrfs/dev-replace.c int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, · line 745
Quoted 8 lines
fs/btrfs/dev-replace.c +2
-0@@ -741,6 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || args->start.tgtdev_name[0 ] =='\0' )return -EINVAL ; + args->start.srcdev_name[BTRFS_PATH_NAME_MAX ] =0 ; + args->start.tgtdev_name[BTRFS_PATH_NAME_MAX ] =0 ;This is not correct,
1. The maximum length oftgtdev_nameisBTRFS_DEVICE_PATH_NAME_MAX+ 1
2. strnlen should be used to confirm the presence of \0 intgtdev_name
3. Input values should not be subjectively updated
Regarding that point I agree it's not the best handling and could be confusing. There are multiple instances of that in the ioctl callbacks so the proper fix is to add a helper doing the validity check (either strnlen or memchr) and then use it.
The pattern to look for is "vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';" in ioctl.c (at least).
Let me know if you'd want to implement that.
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
fs/btrfs/dev-replace.c +2 -0
@@ -741,6 +741,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || args->start.tgtdev_name[0 ] =='\0' )return -EINVAL ; + args->start.srcdev_name[BTRFS_PATH_NAME_MAX ] =0 ; + args->start.tgtdev_name[BTRFS_PATH_NAME_MAX ] =0 ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name, args->start.srcdevid,
syzbot
syzbotsyzbot has tested the proposed patch but the reproducer is still triggering an issue:
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
UBSAN: array-index-out-of-bounds in btrfs_dev_replace_by_ioctl
BTRFS info (device loop0): disabling free space tree
BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE (0x1) BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE_VALID (0x2)
================================================================================
UBSAN: array-index-out-of-bounds in fs/btrfs/dev-replace.c:746:2 index 4087 is out of range for type '__u8[1025]' (aka 'unsigned char[1025]') CPU: 1 PID: 5479 Comm: syz-executor.0 Not tainted 6.7.0-rc5-syzkaller-00200-g3bd7d7488169-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 ubsan_epilogue lib/ubsan.c:217 [inline] __ubsan_handle_out_of_bounds+0x11c/0x150 lib/ubsan.c:348 btrfs_dev_replace_by_ioctl+0x1c1/0x2000 fs/btrfs/dev-replace.c:746 btrfs_ioctl_dev_replace+0x2c9/0x390 fs/btrfs/ioctl.c:3299 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f0c8fe7cba9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f0c90c160c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f0c8ff9bf80 RCX: 00007f0c8fe7cba9 RDX: 0000000020000540 RSI: 00000000ca289435 RDI: 0000000000000005 RBP: 00007f0c8fec847a R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007f0c8ff9bf80 R15: 00007fff3e1d0738 </TASK> ================================================================================
Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git console output: https://syzkaller.appspot.com/x/log.txt?x=12e95ba3e80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=117c0debe80000
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
fs/btrfs/dev-replace.c +1 -0
@@ -741,6 +741,7 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,if ((args->start.srcdevid ==0 && args->start.srcdev_name[0 ] =='\0' ) || args->start.tgtdev_name[0 ] =='\0' )return -EINVAL ; + args->start.tgtdev_name[BTRFS_PATH_NAME_MAX ] ='\0' ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name, args->start.srcdevid,
syzbot
syzbotsyzbot has tested the proposed patch but the reproducer is still triggering an issue:
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
UBSAN: array-index-out-of-bounds in btrfs_dev_replace_by_ioctl
BTRFS info (device loop0): disabling free space tree
BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE (0x1) BTRFS info (device loop0): clearing compat-ro feature flag for FREE_SPACE_TREE_VALID (0x2)
================================================================================
UBSAN: array-index-out-of-bounds in fs/btrfs/dev-replace.c:746:2 index 4087 is out of range for type '__u8[1025]' (aka 'unsigned char[1025]') CPU: 1 PID: 5485 Comm: syz-executor.0 Not tainted 6.7.0-rc5-syzkaller-00200-g3bd7d7488169-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 ubsan_epilogue lib/ubsan.c:217 [inline] __ubsan_handle_out_of_bounds+0x11c/0x150 lib/ubsan.c:348 btrfs_dev_replace_by_ioctl+0x1c1/0x1f10 fs/btrfs/dev-replace.c:746 btrfs_ioctl_dev_replace+0x2c9/0x390 fs/btrfs/ioctl.c:3299 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:871 [inline] __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x45/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f573be7cba9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 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 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f573cc170c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f573bf9bf80 RCX: 00007f573be7cba9 RDX: 0000000020000540 RSI: 00000000ca289435 RDI: 0000000000000005 RBP: 00007f573bec847a R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007f573bf9bf80 R15: 00007fff8c99b838 </TASK> ================================================================================
Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git console output: https://syzkaller.appspot.com/x/log.txt?x=1761a2bde80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=1290befbe80000
please test slab-out-of-bounds Read in getname_kernel
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3bd7d7488169
fs/btrfs/dev-replace.c +1 -0
@@ -742,6 +742,7 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, args->start.tgtdev_name[0] == '\0')return -EINVAL ; + args->start.tgtdev_name[BTRFS_DEVICE_PATH_NAME_MAX ] ='\0' ; ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name, args->start.srcdevid, args->start.srcdev_name,
syzbot
syzbotsyzbot has tested the proposed patch and the reproducer did not trigger any issue:
Hello,
syzbot has tested the proposed patch and the reproducer did not trigger any issue:
Tested on:
commit: 3bd7d748 Merge tag 'io_uring-6.7-2023-12-15' of git://.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git console output: https://syzkaller.appspot.com/x/log.txt?x=13bc50dde80000 kernel config: https://syzkaller.appspot.com/x/.config?x=53ec3da1d259132f dashboard link: https://syzkaller.appspot.com/bug?extid=33f23b49ac24f986c9e8 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=14343dcde80000
Note: testing is done by a robot and is best-effort only.