KASAN: slab-out-of-bounds Write in squashfs_readahead (2)
Subsystems (2)
syzbot
syzbotHello,
syzbot found the following issue on:
HEAD commit: 13d88ac54ddd Merge tag 'vfs-6.7.fsid' of git://git.kernel... git tree: upstream console+strace: https://syzkaller.appspot.com/x/log.txt?x=121965ef680000 kernel config: https://syzkaller.appspot.com/x/.config?x=beb32a598fd79db9 dashboard link: https://syzkaller.appspot.com/bug?extid=604424eb051c2f696163 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=12b40c7b680000 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=10f691ef680000
Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/9e81dc4903c2/disk-13d88ac5.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/f40fd7326b3f/vmlinux-13d88ac5.xz
kernel image: https://storage.googleapis.com/syzbot-assets/2f399cd6ff7d/bzImage-13d88ac5.xz
mounted in repro: https://storage.googleapis.com/syzbot-assets/8e127c645a04/mount_0.gz
The issue was bisected to:
commit f268eedddf3595e85f8883dc50aed29654785696
Author: Phillip Lougher <[email protected]> Date: Sat Jun 11 03:21:32 2022 +0000
squashfs: extend "page actor" to handle missing pages
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=1252b717680000 final oops: https://syzkaller.appspot.com/x/report.txt?x=1152b717680000 console output: https://syzkaller.appspot.com/x/log.txt?x=1652b717680000
IMPORTANT: if you fix the issue, please add the following tag to the commit:
SQUASHFS error: Unable to read metadata cache entry [6fa] SQUASHFS error: Unable to read metadata cache entry [6fa] SQUASHFS error: Unable to read metadata cache entry [6fa]
==================================================================
BUG: KASAN: slab-out-of-bounds in __readahead_batch include/linux/pagemap.h:1364 [inline] BUG: KASAN: slab-out-of-bounds in squashfs_readahead+0x9a6/0x20d0 fs/squashfs/file.c:569 Write of size 8 at addr ffff88801e393648 by task syz-executor100/5067 CPU: 1 PID: 5067 Comm: syz-executor100 Not tainted 6.6.0-syzkaller-15156-g13d88ac54ddd #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/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 __readahead_batch include/linux/pagemap.h:1364 [inline] squashfs_readahead+0x9a6/0x20d0 fs/squashfs/file.c:569 read_pages+0x183/0x830 mm/readahead.c:160 page_cache_ra_unbounded+0x68e/0x7c0 mm/readahead.c:269 page_cache_sync_readahead include/linux/pagemap.h:1266 [inline] filemap_get_pages+0x49c/0x2080 mm/filemap.c:2497 filemap_read+0x42b/0x10b0 mm/filemap.c:2593 __kernel_read+0x425/0x8b0 fs/read_write.c:428 integrity_kernel_read+0xb0/0xf0 security/integrity/iint.c:221 ima_calc_file_hash_tfm security/integrity/ima/ima_crypto.c:485 [inline] ima_calc_file_shash security/integrity/ima/ima_crypto.c:516 [inline] ima_calc_file_hash+0xad1/0x1b30 security/integrity/ima/ima_crypto.c:573 ima_collect_measurement+0x554/0xb30 security/integrity/ima/ima_api.c:290 process_measurement+0x1373/0x21c0 security/integrity/ima/ima_main.c:359 ima_file_check+0xf1/0x170 security/integrity/ima/ima_main.c:557 do_open fs/namei.c:3624 [inline] path_openat+0x2893/0x3280 fs/namei.c:3779 do_filp_open+0x234/0x490 fs/namei.c:3809 do_sys_openat2+0x13e/0x1d0 fs/open.c:1440 do_sys_open fs/open.c:1455 [inline] __do_sys_open fs/open.c:1463 [inline] __se_sys_open fs/open.c:1459 [inline] __x64_sys_open+0x225/0x270 fs/open.c:1459 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f0e73d6c5f9 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:00007ffd516ff158 EFLAGS: 00000246 ORIG_RAX: 0000000000000002 RAX: ffffffffffffffda RBX: 0031656c69662f2e RCX: 00007f0e73d6c5f9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00000000200000c0 RBP: 00007f0e73ddf610 R08: 0000000000000225 R09: 0000000000000000 R10: 00007ffd516ff020 R11: 0000000000000246 R12: 0000000000000001 R13: 00007ffd516ff328 R14: 0000000000000001 R15: 0000000000000001 </TASK> Allocated by task 5067: 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+0xb9/0x230 mm/slab_common.c:1020 kmalloc_array include/linux/slab.h:637 [inline] squashfs_readahead+0x30c/0x20d0 fs/squashfs/file.c:552 read_pages+0x183/0x830 mm/readahead.c:160 page_cache_ra_unbounded+0x68e/0x7c0 mm/readahead.c:269 page_cache_sync_readahead include/linux/pagemap.h:1266 [inline] filemap_get_pages+0x49c/0x2080 mm/filemap.c:2497 filemap_read+0x42b/0x10b0 mm/filemap.c:2593 __kernel_read+0x425/0x8b0 fs/read_write.c:428 integrity_kernel_read+0xb0/0xf0 security/integrity/iint.c:221 ima_calc_file_hash_tfm security/integrity/ima/ima_crypto.c:485 [inline] ima_calc_file_shash security/integrity/ima/ima_crypto.c:516 [inline] ima_calc_file_hash+0xad1/0x1b30 security/integrity/ima/ima_crypto.c:573 ima_collect_measurement+0x554/0xb30 security/integrity/ima/ima_api.c:290 process_measurement+0x1373/0x21c0 security/integrity/ima/ima_main.c:359 ima_file_check+0xf1/0x170 security/integrity/ima/ima_main.c:557 do_open fs/namei.c:3624 [inline] path_openat+0x2893/0x3280 fs/namei.c:3779 do_filp_open+0x234/0x490 fs/namei.c:3809 do_sys_openat2+0x13e/0x1d0 fs/open.c:1440 do_sys_open fs/open.c:1455 [inline] __do_sys_open fs/open.c:1463 [inline] __se_sys_open fs/open.c:1459 [inline] __x64_sys_open+0x225/0x270 fs/open.c:1459 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x63/0x6b The buggy address belongs to the object at ffff88801e393640 which belongs to the cache kmalloc-8 of size 8
The buggy address is located 0 bytes to the right of
allocated 8-byte region [ffff88801e393640, ffff88801e393648)
The buggy address belongs to the physical page:
page:ffffea000078e4c0 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88801e393230 pfn:0x1e393
anon flags: 0xfff00000000800(slab|node=0|zone=1|lastcpupid=0x7ff)
page_type: 0xffffffff()
raw: 00fff00000000800 ffff888012c41280 0000000000000000 dead000000000001
raw: ffff88801e393230 0000000080660063 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 10649202635, free_ts 9358727270
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+0x339a/0x3530 mm/page_alloc.c:3312
__alloc_pages+0x255/0x670 mm/page_alloc.c:4568
alloc_pages_mpol+0x3de/0x640 mm/mempolicy.c:2133
alloc_slab_page+0x6a/0x160 mm/slub.c:1870
allocate_slab mm/slub.c:2017 [inline]
new_slab+0x84/0x2f0 mm/slub.c:2070
___slab_alloc+0xc85/0x1310 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+0xa5/0x230 mm/slab_common.c:1027
kstrdup+0x3a/0x70 mm/util.c:62
__kernfs_new_node+0x9d/0x870 fs/kernfs/dir.c:611
kernfs_new_node+0x99/0x170 fs/kernfs/dir.c:679
kernfs_create_link+0xa5/0x1f0 fs/kernfs/symlink.c:39
sysfs_do_create_link_sd+0x85/0x100 fs/sysfs/symlink.c:44
device_create_sys_dev_entry+0x10f/0x170 drivers/base/core.c:3451
device_add+0x8cf/0xd30 drivers/base/core.c:3595
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+0x92a/0xa50 mm/page_alloc.c:2347
free_unref_page+0x37/0x3f0 mm/page_alloc.c:2487
vfree+0x186/0x2e0 mm/vmalloc.c:2842
delayed_vfree_work+0x56/0x80 mm/vmalloc.c:2763
process_one_work kernel/workqueue.c:2630 [inline]
process_scheduled_works+0x90f/0x1400 kernel/workqueue.c:2703
worker_thread+0xa5f/0xff0 kernel/workqueue.c:2784
kthread+0x2d3/0x370 kernel/kthread.c:388
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:
ffff88801e393500: 00 fc fc fc fc fa fc fc fc fc 05 fc fc fc fc 05
ffff88801e393580: fc fc fc fc 00 fc fc fc fc 05 fc fc fc fc fa fc
>ffff88801e393600: fc fc fc 00 fc fc fc fc 00 fc fc fc fc 00 fc fc
^
ffff88801e393680: fc fc 00 fc fc fc fc 00 fc fc fc fc 00 fc fc fc
ffff88801e393700: fc 00 fc fc fc fc fb fc fc fc fc 00 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
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
For archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/file.c +5 -0
@@ -553,6 +553,9 @@ static void squashfs_readahead(struct readahead_control *ractl)if (!pages)return ; +printk ("p: %p, bs: %d, bl: %d, mp: %d, start: %d, fe: %d, %s\n" , + pages, msblk->block_size, msblk->block_log, + max_pages, start, file_end, __func__);for (;;) {pgoff_t index;int res, bsize;
@@ -566,6 +569,8 @@ static void squashfs_readahead(struct readahead_control *ractl) max_pages = (expected +PAGE_SIZE -1 ) >>PAGE_SHIFT ; +printk ("p: %p, mp: %d, e: %d, idx: %d, s: %d, %s\n" , pages, max_pages, + expected, pages[0 ]->index, start, __func__); nr_pages =__readahead_batch (ractl, pages, max_pages);if (!nr_pages)break ;
fs/squashfs/super.c +2 -0
@@ -275,6 +275,8 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)if (msblk->block_log >SQUASHFS_FILE_MAX_LOG ) goto failed_mount; +printk ("bs: %d, bl: %d, %s\n" , msblk->block_size, msblk->block_log, __func__); +/* Check that block_size and block_log match */ if (msblk->block_size != (1 << msblk->block_log)) goto insanity;
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/file.c +5 -0
@@ -553,6 +553,9 @@ static void squashfs_readahead(struct readahead_control *ractl)if (!pages)return ; +printk ("p: %p, bs: %d, bl: %d, mp: %d, start: %d, fe: %d, %s\n" , + pages, msblk->block_size, msblk->block_log, + max_pages, start, file_end, __func__);for (;;) {pgoff_t index;int res, bsize;
@@ -566,6 +569,8 @@ static void squashfs_readahead(struct readahead_control *ractl) max_pages = (expected +PAGE_SIZE -1 ) >>PAGE_SHIFT ; +printk ("p: %p, mp: %d, e: %d,isr: %d, start: %d, %s\n" , pages, max_pages, + expected,i_size_read (inode), start, __func__); nr_pages =__readahead_batch (ractl, pages, max_pages);if (!nr_pages)break ;
fs/squashfs/super.c +2 -0
@@ -275,6 +275,8 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)if (msblk->block_log >SQUASHFS_FILE_MAX_LOG ) goto failed_mount; +printk ("bs: %d, bl: %d, %s\n" , msblk->block_size, msblk->block_log, __func__); +/* Check that block_size and block_log match */ if (msblk->block_size != (1 << msblk->block_log)) goto insanity;
Quoted 20 lines · syzbot
Hello,
syzbot found the following issue on:
HEAD commit: 13d88ac54ddd Merge tag 'vfs-6.7.fsid' of git://git.kernel... git tree: upstream console+strace: https://syzkaller.appspot.com/x/log.txt?x=121965ef680000 kernel config: https://syzkaller.appspot.com/x/.config?x=beb32a598fd79db9 dashboard link: https://syzkaller.appspot.com/bug?extid=604424eb051c2f696163 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=12b40c7b680000 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=10f691ef680000Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/9e81dc4903c2/disk-13d88ac5.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/f40fd7326b3f/vmlinux-13d88ac5.xz
kernel image: https://storage.googleapis.com/syzbot-assets/2f399cd6ff7d/bzImage-13d88ac5.xz
mounted in repro: https://storage.googleapis.com/syzbot-assets/8e127c645a04/mount_0.gz
Quoted 7 lines
The issue was bisected to:
commit
f268eedddf3595e85f8883dc50aed29654785696Author: Phillip Lougher <[email protected]> Date: Sat Jun 11 03:21:32 2022 +0000squashfs: extend "page actor" to handle missing pages
Fixed the issue, and will send a patch shortly.
Phillip
Quoted 184 lines
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=1252b717680000 final oops: https://syzkaller.appspot.com/x/report.txt?x=1152b717680000 console output: https://syzkaller.appspot.com/x/log.txt?x=1652b717680000IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by [email protected]Fixes f268eedddf35 ("squashfs: extend "page actor" to handle missing pages")SQUASHFS error: Unable to read metadata cache entry [6fa] SQUASHFS error: Unable to read metadata cache entry [6fa] SQUASHFS error: Unable to read metadata cache entry [6fa]
==================================================================BUG: KASAN: slab-out-of-bounds in __readahead_batch include/linux/pagemap.h:1364 [inline] BUG: KASAN: slab-out-of-bounds in squashfs_readahead+0x9a6/0x20d0 fs/squashfs/file.c:569 Write of size 8 at addr ffff88801e393648 by task syz-executor100/5067 CPU: 1 PID: 5067 Comm: syz-executor100 Not tainted 6.6.0-syzkaller-15156-g13d88ac54ddd #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/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 __readahead_batch include/linux/pagemap.h:1364 [inline] squashfs_readahead+0x9a6/0x20d0 fs/squashfs/file.c:569 read_pages+0x183/0x830 mm/readahead.c:160 page_cache_ra_unbounded+0x68e/0x7c0 mm/readahead.c:269 page_cache_sync_readahead include/linux/pagemap.h:1266 [inline] filemap_get_pages+0x49c/0x2080 mm/filemap.c:2497 filemap_read+0x42b/0x10b0 mm/filemap.c:2593 __kernel_read+0x425/0x8b0 fs/read_write.c:428 integrity_kernel_read+0xb0/0xf0 security/integrity/iint.c:221 ima_calc_file_hash_tfm security/integrity/ima/ima_crypto.c:485 [inline] ima_calc_file_shash security/integrity/ima/ima_crypto.c:516 [inline] ima_calc_file_hash+0xad1/0x1b30 security/integrity/ima/ima_crypto.c:573 ima_collect_measurement+0x554/0xb30 security/integrity/ima/ima_api.c:290 process_measurement+0x1373/0x21c0 security/integrity/ima/ima_main.c:359 ima_file_check+0xf1/0x170 security/integrity/ima/ima_main.c:557 do_open fs/namei.c:3624 [inline] path_openat+0x2893/0x3280 fs/namei.c:3779 do_filp_open+0x234/0x490 fs/namei.c:3809 do_sys_openat2+0x13e/0x1d0 fs/open.c:1440 do_sys_open fs/open.c:1455 [inline] __do_sys_open fs/open.c:1463 [inline] __se_sys_open fs/open.c:1459 [inline] __x64_sys_open+0x225/0x270 fs/open.c:1459 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f0e73d6c5f9 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:00007ffd516ff158 EFLAGS: 00000246 ORIG_RAX: 0000000000000002 RAX: ffffffffffffffda RBX: 0031656c69662f2e RCX: 00007f0e73d6c5f9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00000000200000c0 RBP: 00007f0e73ddf610 R08: 0000000000000225 R09: 0000000000000000 R10: 00007ffd516ff020 R11: 0000000000000246 R12: 0000000000000001 R13: 00007ffd516ff328 R14: 0000000000000001 R15: 0000000000000001 </TASK> Allocated by task 5067: 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+0xb9/0x230 mm/slab_common.c:1020 kmalloc_array include/linux/slab.h:637 [inline] squashfs_readahead+0x30c/0x20d0 fs/squashfs/file.c:552 read_pages+0x183/0x830 mm/readahead.c:160 page_cache_ra_unbounded+0x68e/0x7c0 mm/readahead.c:269 page_cache_sync_readahead include/linux/pagemap.h:1266 [inline] filemap_get_pages+0x49c/0x2080 mm/filemap.c:2497 filemap_read+0x42b/0x10b0 mm/filemap.c:2593 __kernel_read+0x425/0x8b0 fs/read_write.c:428 integrity_kernel_read+0xb0/0xf0 security/integrity/iint.c:221 ima_calc_file_hash_tfm security/integrity/ima/ima_crypto.c:485 [inline] ima_calc_file_shash security/integrity/ima/ima_crypto.c:516 [inline] ima_calc_file_hash+0xad1/0x1b30 security/integrity/ima/ima_crypto.c:573 ima_collect_measurement+0x554/0xb30 security/integrity/ima/ima_api.c:290 process_measurement+0x1373/0x21c0 security/integrity/ima/ima_main.c:359 ima_file_check+0xf1/0x170 security/integrity/ima/ima_main.c:557 do_open fs/namei.c:3624 [inline] path_openat+0x2893/0x3280 fs/namei.c:3779 do_filp_open+0x234/0x490 fs/namei.c:3809 do_sys_openat2+0x13e/0x1d0 fs/open.c:1440 do_sys_open fs/open.c:1455 [inline] __do_sys_open fs/open.c:1463 [inline] __se_sys_open fs/open.c:1459 [inline] __x64_sys_open+0x225/0x270 fs/open.c:1459 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x63/0x6b The buggy address belongs to the object at ffff88801e393640 which belongs to the cache kmalloc-8 of size 8The buggy address is located 0 bytes to the right of
allocated 8-byte region [ffff88801e393640,ffff88801e393648)The buggy address belongs to the physical page: page:ffffea000078e4c0 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88801e393230 pfn:0x1e393 anon flags: 0xfff00000000800(slab|node=0|zone=1|lastcpupid=0x7ff) page_type: 0xffffffff() raw: 00fff00000000800 ffff888012c41280 0000000000000000 dead000000000001 raw: ffff88801e393230 0000000080660063 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 10649202635, free_ts 9358727270 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+0x339a/0x3530 mm/page_alloc.c:3312 __alloc_pages+0x255/0x670 mm/page_alloc.c:4568 alloc_pages_mpol+0x3de/0x640 mm/mempolicy.c:2133 alloc_slab_page+0x6a/0x160 mm/slub.c:1870 allocate_slab mm/slub.c:2017 [inline] new_slab+0x84/0x2f0 mm/slub.c:2070 ___slab_alloc+0xc85/0x1310 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+0xa5/0x230 mm/slab_common.c:1027 kstrdup+0x3a/0x70 mm/util.c:62 __kernfs_new_node+0x9d/0x870 fs/kernfs/dir.c:611 kernfs_new_node+0x99/0x170 fs/kernfs/dir.c:679 kernfs_create_link+0xa5/0x1f0 fs/kernfs/symlink.c:39 sysfs_do_create_link_sd+0x85/0x100 fs/sysfs/symlink.c:44 device_create_sys_dev_entry+0x10f/0x170 drivers/base/core.c:3451 device_add+0x8cf/0xd30 drivers/base/core.c:3595 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+0x92a/0xa50 mm/page_alloc.c:2347 free_unref_page+0x37/0x3f0 mm/page_alloc.c:2487 vfree+0x186/0x2e0 mm/vmalloc.c:2842 delayed_vfree_work+0x56/0x80 mm/vmalloc.c:2763 process_one_work kernel/workqueue.c:2630 [inline] process_scheduled_works+0x90f/0x1400 kernel/workqueue.c:2703 worker_thread+0xa5f/0xff0 kernel/workqueue.c:2784 kthread+0x2d3/0x370 kernel/kthread.c:388 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: ffff88801e393500: 00 fc fc fc fc fa fc fc fc fc 05 fc fc fc fc 05 ffff88801e393580: fc fc fc fc 00 fc fc fc fc 05 fc fc fc fc fa fc >ffff88801e393600: fc fc fc 00 fc fc fc fc 00 fc fc fc fc 00 fc fc ^ ffff88801e393680: fc fc 00 fc fc fc fc 00 fc fc fc fc 00 fc fc fc ffff88801e393700: fc 00 fc fc fc fc fb fc fc fc fc 00 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#bisectionIf the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-titleIf you want syzbot to run the reproducer, reply with:
#syz test:git://repo/address.gitbranch-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-reportIf you want to undo deduplication, reply with:
#syz undup
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/file.c +2 -0
@@ -566,6 +566,8 @@ static void squashfs_readahead(struct readahead_control *ractl) max_pages = (expected +PAGE_SIZE -1 ) >>PAGE_SHIFT ; +if (!max_pages) +break ; nr_pages =__readahead_batch (ractl, pages, max_pages);if (!nr_pages)break ;
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/file.c +3 -0
@@ -547,6 +547,9 @@ static void squashfs_readahead(struct readahead_control *ractl)int i, file_end =i_size_read (inode) >> msblk->block_log;unsigned int max_pages =1UL << shift; +if (!file_end && !start) +return ; +readahead_expand (ractl, start, (len | mask) +1 ); pages =kmalloc_array (max_pages,sizeof (void *),GFP_KERNEL );
fs/squashfs/file_direct.c +3 -0
@@ -35,6 +35,9 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize,struct squashfs_page_actor *actor;void *pageaddr; +if (!file_end) +return -EINVAL ; +if (end_index > file_end) end_index = file_end;
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/file.c +8 -0
@@ -461,6 +461,11 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)TRACE ("Entered squashfs_readpage, page index %lx, start block %llx\n" , page->index,squashfs_i (inode)->start); +if (!file_end) { + res = -EINVAL ; + goto out; + } +if (page->index >= ((i_size_read (inode) +PAGE_SIZE -1 ) >>PAGE_SHIFT )) goto out;
@@ -547,6 +552,9 @@ static void squashfs_readahead(struct readahead_control *ractl)int i, file_end =i_size_read (inode) >> msblk->block_log;unsigned int max_pages =1UL << shift; +if (!file_end && !start) +return ; +readahead_expand (ractl, start, (len | mask) +1 ); pages =kmalloc_array (max_pages,sizeof (void *),GFP_KERNEL );
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/file.c +11 -0
@@ -461,6 +461,12 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)TRACE ("Entered squashfs_readpage, page index %lx, start block %llx\n" , page->index,squashfs_i (inode)->start); +if (!file_end) { +printk ("i:%p, is:%d, %s\n" , inode,i_size_read (inode), __func__); + res = -EINVAL ; + goto out; + } +if (page->index >= ((i_size_read (inode) +PAGE_SIZE -1 ) >>PAGE_SHIFT )) goto out;
@@ -547,6 +553,11 @@ static void squashfs_readahead(struct readahead_control *ractl)int i, file_end =i_size_read (inode) >> msblk->block_log;unsigned int max_pages =1UL << shift; +if (!file_end && !start) { +printk ("i:%p, is:%d, %s\n" , inode,i_size_read (inode), __func__); +return ; + } +readahead_expand (ractl, start, (len | mask) +1 ); pages =kmalloc_array (max_pages,sizeof (void *),GFP_KERNEL );
fs/squashfs/inode.c +1 -0
@@ -125,6 +125,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) offset =SQUASHFS_INODE_OFFSET (ino); type =le16_to_cpu (sqshb_ino->inode_type); +printk ("in: %p, fs: %d, it: %d, %s\n" , inode,le32_to_cpu (sqsh_ino->file_size), type, __func__);switch (type) {case SQUASHFS_REG_TYPE : {unsigned int frag_offset, frag;
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/file.c +11 -0
@@ -461,6 +461,12 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)TRACE ("Entered squashfs_readpage, page index %lx, start block %llx\n" , page->index,squashfs_i (inode)->start); +if (!file_end) { +printk ("i:%p, is:%d, %s\n" , inode,i_size_read (inode), __func__); + res = -EINVAL ; + goto out; + } +if (page->index >= ((i_size_read (inode) +PAGE_SIZE -1 ) >>PAGE_SHIFT )) goto out;
@@ -547,6 +553,11 @@ static void squashfs_readahead(struct readahead_control *ractl)int i, file_end =i_size_read (inode) >> msblk->block_log;unsigned int max_pages =1UL << shift; +if (!file_end && !start) { +printk ("i:%p, is:%d, %s\n" , inode,i_size_read (inode), __func__); +return ; + } +readahead_expand (ractl, start, (len | mask) +1 ); pages =kmalloc_array (max_pages,sizeof (void *),GFP_KERNEL );
fs/squashfs/inode.c +2 -0
@@ -403,9 +403,11 @@ int squashfs_read_inode(struct inode *inode, long long ino) }else squashfs_i (inode)->xattr_count =0 ; +printk ("in: %p, fs: %d, it: %d, %s\n" , inode, inode->i_size, type, __func__);return 0 ; failed_read: +printk ("in: %p, fs: %d, it: %d, %s\n" , inode, inode->i_size, type, __func__);ERROR ("Unable to read inode 0x%llx\n" , ino);return err; }
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/block.c +6 -0
@@ -287,6 +287,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,if (index +2 > msblk->bytes_used) { res = -EIO ; +printk ("srd1: i:%d, bu:%d \n" , index, msblk->bytes_used); goto out; } res =squashfs_bio_read (sb, index,2 , &bio, &offset);
@@ -295,6 +296,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,if (WARN_ON_ONCE (!bio_next_segment (bio, &iter_all))) { res = -EIO ; +printk ("srd2 \n" ); goto out_free_bio; }/* Extract the length of the metadata block */
@@ -305,6 +307,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length, }else {if (WARN_ON_ONCE (!bio_next_segment (bio, &iter_all))) { res = -EIO ; +printk ("srd3 \n" ); goto out_free_bio; } data =bvec_virt (bvec);
@@ -324,6 +327,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,if (length <0 || length > output->length || (index + length) > msblk->bytes_used) { res = -EIO ; +printk ("srd4: l:%d, ol: %d, bu: %d \n" , length, output->length, msblk->bytes_used); goto out; }
@@ -336,10 +340,12 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,if (compressed) {if (!msblk->stream) { +printk ("srd5 \n" ); res = -EIO ; goto out_free_bio; } res = msblk->thread_ops->decompress (msblk, bio, offset, length, output); +printk ("srd6: r: %d \n" , res); }else { res =copy_bio_to_actor (bio, output, offset, length); }
fs/squashfs/file.c +11 -0
@@ -461,6 +461,12 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)TRACE ("Entered squashfs_readpage, page index %lx, start block %llx\n" , page->index,squashfs_i (inode)->start); +if (!file_end) { +printk ("i:%p, is:%d, %s\n" , inode,i_size_read (inode), __func__); + res = -EINVAL ; + goto out; + } +if (page->index >= ((i_size_read (inode) +PAGE_SIZE -1 ) >>PAGE_SHIFT )) goto out;
@@ -547,6 +553,11 @@ static void squashfs_readahead(struct readahead_control *ractl)int i, file_end =i_size_read (inode) >> msblk->block_log;unsigned int max_pages =1UL << shift; +if (!file_end && !start) { +printk ("i:%p, is:%d, %s\n" , inode,i_size_read (inode), __func__); +return ; + } +readahead_expand (ractl, start, (len | mask) +1 ); pages =kmalloc_array (max_pages,sizeof (void *),GFP_KERNEL );
fs/squashfs/inode.c +2 -0
@@ -403,9 +403,11 @@ int squashfs_read_inode(struct inode *inode, long long ino) }else squashfs_i (inode)->xattr_count =0 ; +printk ("in: %p, fs: %d, it: %d, %s\n" , inode, inode->i_size, type, __func__);return 0 ; failed_read: +printk ("in: %p, fs: %d, it: %d, %s\n" , inode, inode->i_size, type, __func__);ERROR ("Unable to read inode 0x%llx\n" , ino);return err; }
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/block.c +4 -0
@@ -314,9 +314,11 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,bio_uninit (bio);kfree (bio); +printk ("datal: %d \n" , length); compressed =SQUASHFS_COMPRESSED (length); length =SQUASHFS_COMPRESSED_SIZE (length); index +=2 ; +printk ("datal2: %d, c:%d, i:%d \n" , length, compressed, index);TRACE ("Block @ 0x%llx, %scompressed size %d\n" , index -2 , compressed ?"" :"un" , length);
@@ -324,6 +326,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,if (length <0 || length > output->length || (index + length) > msblk->bytes_used) { res = -EIO ; +printk ("srd: l:%d, ol: %d, bu: %d \n" , length, output->length, msblk->bytes_used); goto out; }
@@ -340,6 +343,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length, goto out_free_bio; } res = msblk->thread_ops->decompress (msblk, bio, offset, length, output); +printk ("srd6: r: %d \n" , res); }else { res =copy_bio_to_actor (bio, output, offset, length); }
fs/squashfs/cache.c +3 -0
@@ -340,6 +340,7 @@ int squashfs_read_metadata(struct super_block *sb, void *buffer,if (unlikely (length <0 ))return -EIO ; +printk ("srm: %d\n" , length);while (length) { entry =squashfs_cache_get (sb, msblk->block_cache, *block,0 );if (entry->error) {
@@ -381,6 +382,7 @@ struct squashfs_cache_entry *squashfs_get_fragment(struct super_block *sb, {struct squashfs_sb_info *msblk = sb->s_fs_info; +printk ("sgf: %d\n" , length);return squashfs_cache_get (sb, msblk->fragment_cache, start_block, length); }
@@ -396,6 +398,7 @@ struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *sb, {struct squashfs_sb_info *msblk = sb->s_fs_info; +printk ("sgd: %d\n" , length);return squashfs_cache_get (sb, msblk->read_page, start_block, length); }
fs/squashfs/file.c +11 -0
@@ -461,6 +461,12 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)TRACE ("Entered squashfs_readpage, page index %lx, start block %llx\n" , page->index,squashfs_i (inode)->start); +if (!file_end) { +printk ("i:%p, is:%d, %s\n" , inode,i_size_read (inode), __func__); + res = -EINVAL ; + goto out; + } +if (page->index >= ((i_size_read (inode) +PAGE_SIZE -1 ) >>PAGE_SHIFT )) goto out;
@@ -547,6 +553,11 @@ static void squashfs_readahead(struct readahead_control *ractl)int i, file_end =i_size_read (inode) >> msblk->block_log;unsigned int max_pages =1UL << shift; +if (!file_end && !start) { +printk ("i:%p, is:%d, %s\n" , inode,i_size_read (inode), __func__); +return ; + } +readahead_expand (ractl, start, (len | mask) +1 ); pages =kmalloc_array (max_pages,sizeof (void *),GFP_KERNEL );
fs/squashfs/inode.c +2 -0
@@ -175,6 +175,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)u64 frag_blk;struct squashfs_lreg_inode *sqsh_ino = &squashfs_ino.lreg; +printk ("in0: %p, fs: %d, it: %d, %s\n" , inode, inode->i_size, type, __func__); err =squashfs_read_metadata (sb, sqsh_ino, &block, &offset,sizeof (*sqsh_ino));if (err <0 )
@@ -403,6 +404,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) }else squashfs_i (inode)->xattr_count =0 ; +printk ("in: %p, fs: %d, it: %d, %s\n" , inode, inode->i_size, type, __func__);return 0 ; failed_read:
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/block.c +7 -2
@@ -321,11 +321,16 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,TRACE ("Block @ 0x%llx, %scompressed size %d\n" , index -2 , compressed ?"" :"un" , length); } -if (length <0 || length > output->length || - (index + length) > msblk->bytes_used) { + +if (length <0 ) { res = -EIO ; goto out; } +if (length > output->length || (index + length) > msblk->bytes_used) { +printk ("srd: l:%d, ol: %d, bu: %d,i:%d, c:%d \n" , length, + output->length, msblk->bytes_used, index, compressed); + length =min_t (int, msblk->bytes_used - index, output->length); + }if (next_index) *next_index = index + length;
fs/squashfs/file.c +11 -0
@@ -461,6 +461,12 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)TRACE ("Entered squashfs_readpage, page index %lx, start block %llx\n" , page->index,squashfs_i (inode)->start); +if (!file_end) { +printk ("i:%p, is:%d, %s\n" , inode,i_size_read (inode), __func__); + res = -EINVAL ; + goto out; + } +if (page->index >= ((i_size_read (inode) +PAGE_SIZE -1 ) >>PAGE_SHIFT )) goto out;
@@ -547,6 +553,11 @@ static void squashfs_readahead(struct readahead_control *ractl)int i, file_end =i_size_read (inode) >> msblk->block_log;unsigned int max_pages =1UL << shift; +if (!file_end && !start) { +printk ("i:%p, is:%d, %s\n" , inode,i_size_read (inode), __func__); +return ; + } +readahead_expand (ractl, start, (len | mask) +1 ); pages =kmalloc_array (max_pages,sizeof (void *),GFP_KERNEL );
fs/squashfs/inode.c +2 -0
@@ -175,6 +175,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)u64 frag_blk;struct squashfs_lreg_inode *sqsh_ino = &squashfs_ino.lreg; +printk ("in0: %p, fs: %d, it: %d, %s\n" , inode, inode->i_size, type, __func__); err =squashfs_read_metadata (sb, sqsh_ino, &block, &offset,sizeof (*sqsh_ino));if (err <0 )
@@ -403,6 +404,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) }else squashfs_i (inode)->xattr_count =0 ; +printk ("in: %p, fs: %d, it: %d, %s\n" , inode, inode->i_size, type, __func__);return 0 ; failed_read:
syzbot
syzbotRe: [syzbot] [PATCH] Test oob in squashfs readahead
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [PATCH] Test oob in squashfs readahead
Author: [email protected]
please test squashfs readahead oob
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 13d88ac54ddd
fs/squashfs/block.c +1 -1
@@ -323,7 +323,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length, }if (length <0 || length > output->length || (index + length) > msblk->bytes_used) { - res = -EIO ; + res = length <0 ? -EIO : -EFBIG ; goto out; }
fs/squashfs/file.c +8 -0
@@ -461,6 +461,11 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)TRACE ("Entered squashfs_readpage, page index %lx, start block %llx\n" , page->index,squashfs_i (inode)->start); +if (!file_end) { + res = -EINVAL ; + goto out; + } +if (page->index >= ((i_size_read (inode) +PAGE_SIZE -1 ) >>PAGE_SHIFT )) goto out;
@@ -547,6 +552,9 @@ static void squashfs_readahead(struct readahead_control *ractl)int i, file_end =i_size_read (inode) >> msblk->block_log;unsigned int max_pages =1UL << shift; +if (!file_end) +return ; +readahead_expand (ractl, start, (len | mask) +1 ); pages =kmalloc_array (max_pages,sizeof (void *),GFP_KERNEL );
PATCH 1/1 squashfs: fix oob in squashfs_readahead
In reply to syzbot[Syz log]
SQUASHFS error: Failed to read block 0x6fc: -5 SQUASHFS error: Unable to read metadata cache entry [6fa] SQUASHFS error: Unable to read metadata cache entry [6fa] SQUASHFS error: Unable to read metadata cache entry [6fa]
==================================================================
BUG: KASAN: slab-out-of-bounds in __readahead_batch include/linux/pagemap.h:1364 [inline] BUG: KASAN: slab-out-of-bounds in squashfs_readahead+0x9a6/0x20d0 fs/squashfs/file.c:569 Write of size 8 at addr ffff88801e393648 by task syz-executor100/5067 CPU: 1 PID: 5067 Comm: syz-executor100 Not tainted 6.6.0-syzkaller-15156-g13d88ac54ddd #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/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 __readahead_batch include/linux/pagemap.h:1364 [inline] squashfs_readahead+0x9a6/0x20d0 fs/squashfs/file.c:569 read_pages+0x183/0x830 mm/readahead.c:160 page_cache_ra_unbounded+0x68e/0x7c0 mm/readahead.c:269 page_cache_sync_readahead include/linux/pagemap.h:1266 [inline] filemap_get_pages+0x49c/0x2080 mm/filemap.c:2497 filemap_read+0x42b/0x10b0 mm/filemap.c:2593 __kernel_read+0x425/0x8b0 fs/read_write.c:428 integrity_kernel_read+0xb0/0xf0 security/integrity/iint.c:221 ima_calc_file_hash_tfm security/integrity/ima/ima_crypto.c:485 [inline] ima_calc_file_shash security/integrity/ima/ima_crypto.c:516 [inline] ima_calc_file_hash+0xad1/0x1b30 security/integrity/ima/ima_crypto.c:573 ima_collect_measurement+0x554/0xb30 security/integrity/ima/ima_api.c:290 process_measurement+0x1373/0x21c0 security/integrity/ima/ima_main.c:359 ima_file_check+0xf1/0x170 security/integrity/ima/ima_main.c:557 do_open fs/namei.c:3624 [inline] path_openat+0x2893/0x3280 fs/namei.c:3779
[Bug]path_openat() called open_last_lookups() before calling do_open() and open_last_lookups() will eventually call squashfs_read_inode() to set inode->i_size, but before setting i_size, it is necessary to obtain file_size from the disk.
However, during the value retrieval process, the length of the value retrieved from the disk was greater than output->length, resulting(-EIO) in the failure of squashfs_read_data(), further leading to i_size has not been initialized, i.e. its value is 0.
This resulted in the failure of squashfs_read_data(), where "SQUASHFS error:
Failed to read block 0x6fc: -5" was output in the syz log.
This also resulted in the failure of squashfs_cache_get(), outputting "SQUASHFS
error: Unable to read metadata cache entry [6fa]" in the syz log.
[Fix]
Before performing a read ahead operation in squashfs_read_folio() and squashfs_readahead(), check if i_size is not 0 before continuing.
Optimize the return value of squashfs_read_data() and return -EFBIG when the length is greater than output->length(or (index + length) > msblk->bytes_used).
--- fs/squashfs/block.c | 2 +- fs/squashfs/file.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-)
fs/squashfs/block.c +1 -1
@@ -323,7 +323,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length, }if (length <0 || length > output->length || (index + length) > msblk->bytes_used) { - res = -EIO ; + res = length <0 ? -EIO : -EFBIG ; goto out; }
fs/squashfs/file.c +8 -0
@@ -461,6 +461,11 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)TRACE ("Entered squashfs_readpage, page index %lx, start block %llx\n" , page->index,squashfs_i (inode)->start); +if (!file_end) { + res = -EINVAL ; + goto out; + } +if (page->index >= ((i_size_read (inode) +PAGE_SIZE -1 ) >>PAGE_SHIFT )) goto out;
@@ -547,6 +552,9 @@ static void squashfs_readahead(struct readahead_control *ractl)int i, file_end =i_size_read (inode) >> msblk->block_log;unsigned int max_pages =1UL << shift; +if (!file_end) +return ; +readahead_expand (ractl, start, (len | mask) +1 ); pages =kmalloc_array (max_pages,sizeof (void *),GFP_KERNEL );
Signature · 1 line
2.25.1
Re: [PATCH] squashfs: fix oob in squashfs_readahead
Quoted 2 lines · On Wed, 15 Nov 2023 12:05:35 +0800 Edward Adam Davis <[email protected]> wrote:
Before performing a read ahead operation in
squashfs_read_folio()andsquashfs_readahead(), check ifi_sizeis not 0 before continuing.
I'll merge this for testing, pending Phillip's review. One thing:
fs/squashfs/block.c int squashfs_read_data(struct super_block *sb, u64 index, int length, · line 328
Quoted 10 lines
fs/squashfs/block.c +1
-1@@ -323,7 +323,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length, }if (length <0 || length > output->length || (index + length) > msblk->bytes_used) { - res = -EIO ; + res = length <0 ? -EIO : -EFBIG ; goto out; }
Seems a bit ugly to test `length' twice for the same thing. How about
if (length < 0) {
res = -EIO;
got out;
}
if (length > output->length || (index + length) > msblk->bytes_used) {
res = -EFBIG;
goto out;
}?
Re: [PATCH] squashfs: fix oob in squashfs_readahead
In reply to Edward Adam DavisQuoted 11 lines
[Bug]
path_openat()calledopen_last_lookups()before callingdo_open()andopen_last_lookups()will eventually callsquashfs_read_inode()to setinode->i_size, but before settingi_size, it is necessary to obtainfile_sizefrom the disk.However, during the value retrieval process, the length of the value retrieved from the disk was greater than
output->length, resulting(-EIO) in the failure ofsquashfs_read_data(), further leading toi_sizehas not been initialized, i.e. its value is 0.
NACK
This analysis is completely *wrong*. First, if there was I/O error reading the inode it would never be created, and squasfs_readahead() would never be called on it, because it will never exist.
Second i_size isn't unintialised and it isn't 0 in value. Where you got this bogus information from is because in your test patches, i.e.
https://lore.kernel.org/all/[email protected]/
You have
+ if (!file_end) {
+ printk("i:%p, is:%d, %s\n", inode, i_size_read(inode), __func__);
+ res = -EINVAL;
+ goto out;
+ }
+
You have used %d, and the result of i_size_read(inode) overflows, giving the bogus 0 value.
The actual value is 1407374883553280, or 0x5000000000000, which is too big to fit into an unsigned int.
Quoted 5 lines
This resulted in the failure of
squashfs_read_data(), where "SQUASHFS error:
Failed to read block0x6fc: -5" was output in the syz log.
This also resulted in the failure ofsquashfs_cache_get(), outputting "SQUASHFS
error: Unable to read metadata cache entry [6fa]" in the syz log.
NO, *that* is caused by the failure to read some other inodes which as a result are correctly not created. Nothing to do with the oops here.
Quoted 4 lines
[Fix]
Before performing a read ahead operation insquashfs_read_folio()andsquashfs_readahead(), check ifi_sizeis not 0 before continuing.
A third NO, it is only 0 because the variable overflowed.
Additionally, let's look at your "fix" here.
fs/squashfs/file.c static int squashfs_read_folio(struct file *file, struct folio *folio) · line 468
Quoted 9 lines
fs/squashfs/file.c +5
-0@@ -461,6 +461,11 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)TRACE ("Entered squashfs_readpage, page index %lx, start block %llx\n" , page->index,squashfs_i (inode)->start); +if (!file_end) { + res = -EINVAL ; + goto out; + } +
file_end is computed by
int file_end = i_size_read(inode) >> msblk->block_log;
So your "fix" will reject *any* file less than msblk->block_log in size as invalid, including perfectly valid zero size files (empty files are valid too).
I already identified the cause and send a fix patch here:
https://lore.kernel.org/all/[email protected]/
NACK
Phillip
Re: [PATCH] squashfs: fix oob in squashfs_readahead
Quoted 14 lines · Phillip Lougher
Quoted 11 lines
[Bug]
path_openat()calledopen_last_lookups()before callingdo_open()andopen_last_lookups()will eventually callsquashfs_read_inode()to setinode->i_size, but before settingi_size, it is necessary to obtainfile_sizefrom the disk.However, during the value retrieval process, the length of the value retrieved from the disk was greater than
output->length, resulting(-EIO) in the failure ofsquashfs_read_data(), further leading toi_sizehas not been initialized, i.e. its value is 0.NACK
Quoted 7 lines
This analysis is completely *wrong*. First, if there was I/O error reading the inode it would never be created, and
squasfs_readahead()would never be called on it, because it will never exist.Second
i_sizeisn't unintialised and it isn't 0 in value. Where you got this bogus information from is because in your test patches, i.e.
[There is my debuging patch]
fs/squashfs/block.c +3 -0
@@ -314,9 +314,11 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,bio_uninit (bio);kfree (bio); +printk ("datal: %d \n" , length); compressed =SQUASHFS_COMPRESSED (length); length =SQUASHFS_COMPRESSED_SIZE (length); index +=2 ; +printk ("datal2: %d, c:%d, i:%d \n" , length, compressed, index);TRACE ("Block @ 0x%llx, %scompressed size %d\n" , index -2 , compressed ?"" :"un" , length);
@@ -324,6 +326,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,if (length <0 || length > output->length || (index + length) > msblk->bytes_used) { res = -EIO ; +printk ("srd: l:%d, ol: %d, bu: %d \n" , length, output->length, msblk->bytes_used); goto out; }
patch link: https://syzkaller.appspot.com/text?tag=Patch&x=1142f82f680000
[There is my test log]
[ 457.030754][ T8879] datal: 65473 [ 457.034334][ T8879] datal2: 32705, c:0, i:1788 [ 457.039253][ T8879] srd: l:32705, ol: 8192, bu: 1870 [ 457.044513][ T8879] SQUASHFS error: Failed to read block 0x6fc: -5 [ 457.052034][ T8879] SQUASHFS error: Unable to read metadata cache entry [6fa]
log link: https://syzkaller.appspot.com/x/log.txt?x=137b0270e80000
[Answer your doubts]
Based on the above test, it can be clearly determined that length=32705 is greater than the maximum metadata size of 8192, resulting in squashfs_read_data() failed. This will further lead to squashfs_cache_get() returns "entry->error=entry->length=-EIO", followed by squashfs_read_metadata() failed, which will ultimately result in i_size not being initialized in squashfs_read_inode().
The following are the relevant call stacks:
23 const struct inode_operations squashfs_dir_inode_ops = {
24 .lookup = squashfs_lookup,
25 .listxattr = squashfs_listxattr
26 };
NORMAL +0 ~0 -0 fs/squashfs/namei.c
path_openat()->open_last_lookups()->lookup_open()
1 if (d_in_lookup(dentry)) { 3455 struct dentry *res = dir_inode->i_op->lookup(dir_inode, dentry, 1 nd->flags);
squashfs_lookup()->
squashfs_iget()-> squashfs_read_inode()-> init inode->i_size, example: inode->i_size = sqsh_ino->file_size;
Quoted 48 lines
https://lore.kernel.org/all/[email protected]/
You have
(quoted diff) +6
-0+ if (!file_end) { + printk("i:%p, is:%d, %s\n", inode, i_size_read(inode), __func__); + res = -EINVAL; + goto out; + } +You have used %d, and the result of
i_size_read(inode)overflows, giving the bogus 0 value.The actual value is 1407374883553280, or
0x5000000000000, which is too big to fit into an unsigned int.Quoted 5 lines
This resulted in the failure of
squashfs_read_data(), where "SQUASHFS error:
Failed to read block0x6fc: -5" was output in the syz log.
This also resulted in the failure ofsquashfs_cache_get(), outputting "SQUASHFS
error: Unable to read metadata cache entry [6fa]" in the syz log.NO, *that* is caused by the failure to read some other inodes which as a result are correctly not created. Nothing to do with the oops here.
Quoted 4 lines
[Fix]
Before performing a read ahead operation insquashfs_read_folio()andsquashfs_readahead(), check ifi_sizeis not 0 before continuing.A third NO, it is only 0 because the variable overflowed.
Additionally, let's look at your "fix" here.
Review static int squashfs_read_folio(struct file *file, struct folio *folio) · line 468
Quoted 9 lines
(quoted diff) +5
-0@@ -461,6 +461,11 @@ static int squashfs_read_folio(struct file *file, struct folio *folio) TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n", page->index, squashfs_i(inode)->start); + if (!file_end) { + res = -EINVAL; + goto out; + } +
file_endis computed by
Quoted 5 lines
int file_end = i_size_read(inode) >> msblk->block_log;So your "fix" will reject *any* file less than
msblk->block_login size as invalid, including perfectly valid zero size files (empty files are valid too).
edward
Re: [PATCH] squashfs: fix oob in squashfs_readahead
In reply to Edward Adam DavisHi All,
Quoted 57 lines · Edward Adam Davis
[Syz log]
SQUASHFS error: Failed to read block0x6fc: -5 SQUASHFS error: Unable to read metadata cache entry [6fa] SQUASHFS error: Unable to read metadata cache entry [6fa] SQUASHFS error: Unable to read metadata cache entry [6fa]
==================================================================BUG: KASAN: slab-out-of-bounds in __readahead_batch include/linux/pagemap.h:1364 [inline] BUG: KASAN: slab-out-of-bounds in squashfs_readahead+0x9a6/0x20d0 fs/squashfs/file.c:569 Write of size 8 at addr ffff88801e393648 by task syz-executor100/5067 CPU: 1 PID: 5067 Comm: syz-executor100 Not tainted 6.6.0-syzkaller-15156-g13d88ac54ddd #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/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 __readahead_batch include/linux/pagemap.h:1364 [inline] squashfs_readahead+0x9a6/0x20d0 fs/squashfs/file.c:569 read_pages+0x183/0x830 mm/readahead.c:160 page_cache_ra_unbounded+0x68e/0x7c0 mm/readahead.c:269 page_cache_sync_readahead include/linux/pagemap.h:1266 [inline] filemap_get_pages+0x49c/0x2080 mm/filemap.c:2497 filemap_read+0x42b/0x10b0 mm/filemap.c:2593 __kernel_read+0x425/0x8b0 fs/read_write.c:428 integrity_kernel_read+0xb0/0xf0 security/integrity/iint.c:221 ima_calc_file_hash_tfm security/integrity/ima/ima_crypto.c:485 [inline] ima_calc_file_shash security/integrity/ima/ima_crypto.c:516 [inline] ima_calc_file_hash+0xad1/0x1b30 security/integrity/ima/ima_crypto.c:573 ima_collect_measurement+0x554/0xb30 security/integrity/ima/ima_api.c:290 process_measurement+0x1373/0x21c0 security/integrity/ima/ima_main.c:359 ima_file_check+0xf1/0x170 security/integrity/ima/ima_main.c:557 do_open fs/namei.c:3624 [inline] path_openat+0x2893/0x3280 fs/namei.c:3779[Bug]
path_openat()calledopen_last_lookups()before callingdo_open()andopen_last_lookups()will eventually callsquashfs_read_inode()to setinode->i_size, but before settingi_size, it is necessary to obtainfile_sizefrom the disk.However, during the value retrieval process, the length of the value retrieved from the disk was greater than
output->length, resulting(-EIO) in the failure ofsquashfs_read_data(), further leading toi_sizehas not been initialized, i.e. its value is 0.This resulted in the failure of
squashfs_read_data(), where "SQUASHFS error:
Failed to read block0x6fc: -5" was output in the syz log.
This also resulted in the failure ofsquashfs_cache_get(), outputting "SQUASHFS
error: Unable to read metadata cache entry [6fa]" in the syz log.[Fix]
Before performing a read ahead operation insquashfs_read_folio()andsquashfs_readahead(), check ifi_sizeis not 0 before continuing.
Quoted 7 lines
Optimize the return value of
squashfs_read_data()and return-EFBIGwhen the length is greater thanoutput->length(or (index + length) > msblk->bytes_used).Reported-and-tested-by [email protected]Fixes f268eedddf35 ("squashfs: extend "page actor" to handle missing pages")Signed-off-by Edward Adam Davis <[email protected]>
This patch, merged to linux-next as commit 1ff947abe24a ("squashfs: fix oob in squashfs_readahead"), breaks mounting squashfs volumes on all my test systems. Let me know if you need more information to debug this issue.
Quoted 35 lines
--- fs/squashfs/block.c | 2 +- fs/squashfs/file.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-)fs/squashfs/block.c +1
-1@@ -323,7 +323,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length, }if (length <0 || length > output->length || (index + length) > msblk->bytes_used) { - res = -EIO ; + res = length <0 ? -EIO : -EFBIG ; goto out; }fs/squashfs/file.c +5
-0@@ -461,6 +461,11 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)TRACE ("Entered squashfs_readpage, page index %lx, start block %llx\n" , page->index,squashfs_i (inode)->start); +if (!file_end) { + res = -EINVAL ; + goto out; + } +if (page->index >= ((i_size_read (inode) +PAGE_SIZE -1 ) >>PAGE_SHIFT )) goto out;
fs/squashfs/file.c static void squashfs_readahead(struct readahead_control *ractl) · line 560
Quoted 9 lines
fs/squashfs/file.c +3
-0@@ -547,6 +552,9 @@ static void squashfs_readahead(struct readahead_control *ractl)int i, file_end =i_size_read (inode) >> msblk->block_log;unsigned int max_pages =1UL << shift; +if (!file_end) +return ; +readahead_expand (ractl, start, (len | mask) +1 ); pages =kmalloc_array (max_pages,sizeof (void *),GFP_KERNEL );
Best regards
Signature · 2 lines
Marek Szyprowski, PhD Samsung R&D Institute Poland
Re: [PATCH] squashfs: fix oob in squashfs_readahead
Quoted 7 lines · On Fri, 17 Nov 2023 14:17:17 +0100 Marek Szyprowski <[email protected]>…
Quoted 3 lines
Reported-and-tested-by [email protected]Fixes f268eedddf35 ("squashfs: extend "page actor" to handle missing pages")Signed-off-by Edward Adam Davis <[email protected]>This patch, merged to linux-next as commit
1ff947abe24a("squashfs: fix oob insquashfs_readahead"), breaks mounting squashfs volumes on all my test systems. Let me know if you need more information to debug this issue.
Thanks. The patch has been dropped.