Message ID | 7eb2d171cdb1a2a89288a989dc0ef28c21bebc59.1713361686.git.jth@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] btrfs: fix information leak in btrfs_ioctl_logical_to_ino() | expand |
On Wed, Apr 17, 2024 at 2:49 PM Johannes Thumshirn <jth@kernel.org> wrote: > > From: Johannes Thumshirn <johannes.thumshirn@wdc.com> > > Syzbot reported the following information leak for in > btrfs_ioctl_logical_to_ino(): > > BUG: KMSAN: kernel-infoleak in instrument_copy_to_user include/linux/instrumented.h:114 [inline] > BUG: KMSAN: kernel-infoleak in _copy_to_user+0xbc/0x110 lib/usercopy.c:40 > instrument_copy_to_user include/linux/instrumented.h:114 [inline] > _copy_to_user+0xbc/0x110 lib/usercopy.c:40 > copy_to_user include/linux/uaccess.h:191 [inline] > btrfs_ioctl_logical_to_ino+0x440/0x750 fs/btrfs/ioctl.c:3499 > btrfs_ioctl+0x714/0x1260 > vfs_ioctl fs/ioctl.c:51 [inline] > __do_sys_ioctl fs/ioctl.c:904 [inline] > __se_sys_ioctl+0x261/0x450 fs/ioctl.c:890 > __x64_sys_ioctl+0x96/0xe0 fs/ioctl.c:890 > x64_sys_call+0x1883/0x3b50 arch/x86/include/generated/asm/syscalls_64.h:17 > do_syscall_x64 arch/x86/entry/common.c:52 [inline] > do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Uninit was created at: > __kmalloc_large_node+0x231/0x370 mm/slub.c:3921 > __do_kmalloc_node mm/slub.c:3954 [inline] > __kmalloc_node+0xb07/0x1060 mm/slub.c:3973 > kmalloc_node include/linux/slab.h:648 [inline] > kvmalloc_node+0xc0/0x2d0 mm/util.c:634 > kvmalloc include/linux/slab.h:766 [inline] > init_data_container+0x49/0x1e0 fs/btrfs/backref.c:2779 > btrfs_ioctl_logical_to_ino+0x17c/0x750 fs/btrfs/ioctl.c:3480 > btrfs_ioctl+0x714/0x1260 > vfs_ioctl fs/ioctl.c:51 [inline] > __do_sys_ioctl fs/ioctl.c:904 [inline] > __se_sys_ioctl+0x261/0x450 fs/ioctl.c:890 > __x64_sys_ioctl+0x96/0xe0 fs/ioctl.c:890 > x64_sys_call+0x1883/0x3b50 arch/x86/include/generated/asm/syscalls_64.h:17 > do_syscall_x64 arch/x86/entry/common.c:52 [inline] > do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Bytes 40-65535 of 65536 are uninitialized > Memory access of size 65536 starts at ffff888045a40000 > > This happens, because we're copying a 'struct btrfs_data_container' back > to user-space. This btrfs_data_container is allocated in > 'init_data_container()' via kvmalloc(), which does not zero-fill the > memory. > > Fix this by using kvzalloc() which zeroes out the memory on allocation. > > Reported-by: <syzbot+510a1abbb8116eeb341d@syzkaller.appspotmail.com> > Signed-off-by: Johannes Thumshirn <Johannes.thumshirn@wdc.com> > Reviewed-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Looks good, thanks. > --- > fs/btrfs/backref.c | 12 +++--------- > 1 file changed, 3 insertions(+), 9 deletions(-) > > diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c > index 0bc81b340295..a2de5c05f97c 100644 > --- a/fs/btrfs/backref.c > +++ b/fs/btrfs/backref.c > @@ -2770,20 +2770,14 @@ struct btrfs_data_container *init_data_container(u32 total_bytes) > size_t alloc_bytes; > > alloc_bytes = max_t(size_t, total_bytes, sizeof(*data)); > - data = kvmalloc(alloc_bytes, GFP_KERNEL); > + data = kvzalloc(alloc_bytes, GFP_KERNEL); > if (!data) > return ERR_PTR(-ENOMEM); > > - if (total_bytes >= sizeof(*data)) { > + if (total_bytes >= sizeof(*data)) > data->bytes_left = total_bytes - sizeof(*data); > - data->bytes_missing = 0; > - } else { > + else > data->bytes_missing = sizeof(*data) - total_bytes; > - data->bytes_left = 0; > - } > - > - data->elem_cnt = 0; > - data->elem_missed = 0; > > return data; > } > -- > 2.35.3 >
On Wed, Apr 17, 2024 at 03:48:49PM +0200, Johannes Thumshirn wrote: > From: Johannes Thumshirn <johannes.thumshirn@wdc.com> > > Syzbot reported the following information leak for in > btrfs_ioctl_logical_to_ino(): > > BUG: KMSAN: kernel-infoleak in instrument_copy_to_user include/linux/instrumented.h:114 [inline] > BUG: KMSAN: kernel-infoleak in _copy_to_user+0xbc/0x110 lib/usercopy.c:40 > instrument_copy_to_user include/linux/instrumented.h:114 [inline] > _copy_to_user+0xbc/0x110 lib/usercopy.c:40 > copy_to_user include/linux/uaccess.h:191 [inline] > btrfs_ioctl_logical_to_ino+0x440/0x750 fs/btrfs/ioctl.c:3499 > btrfs_ioctl+0x714/0x1260 > vfs_ioctl fs/ioctl.c:51 [inline] > __do_sys_ioctl fs/ioctl.c:904 [inline] > __se_sys_ioctl+0x261/0x450 fs/ioctl.c:890 > __x64_sys_ioctl+0x96/0xe0 fs/ioctl.c:890 > x64_sys_call+0x1883/0x3b50 arch/x86/include/generated/asm/syscalls_64.h:17 > do_syscall_x64 arch/x86/entry/common.c:52 [inline] > do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Uninit was created at: > __kmalloc_large_node+0x231/0x370 mm/slub.c:3921 > __do_kmalloc_node mm/slub.c:3954 [inline] > __kmalloc_node+0xb07/0x1060 mm/slub.c:3973 > kmalloc_node include/linux/slab.h:648 [inline] > kvmalloc_node+0xc0/0x2d0 mm/util.c:634 > kvmalloc include/linux/slab.h:766 [inline] > init_data_container+0x49/0x1e0 fs/btrfs/backref.c:2779 > btrfs_ioctl_logical_to_ino+0x17c/0x750 fs/btrfs/ioctl.c:3480 > btrfs_ioctl+0x714/0x1260 > vfs_ioctl fs/ioctl.c:51 [inline] > __do_sys_ioctl fs/ioctl.c:904 [inline] > __se_sys_ioctl+0x261/0x450 fs/ioctl.c:890 > __x64_sys_ioctl+0x96/0xe0 fs/ioctl.c:890 > x64_sys_call+0x1883/0x3b50 arch/x86/include/generated/asm/syscalls_64.h:17 > do_syscall_x64 arch/x86/entry/common.c:52 [inline] > do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Bytes 40-65535 of 65536 are uninitialized > Memory access of size 65536 starts at ffff888045a40000 > > This happens, because we're copying a 'struct btrfs_data_container' back > to user-space. This btrfs_data_container is allocated in > 'init_data_container()' via kvmalloc(), which does not zero-fill the > memory. > > Fix this by using kvzalloc() which zeroes out the memory on allocation. > > Reported-by: <syzbot+510a1abbb8116eeb341d@syzkaller.appspotmail.com> > Signed-off-by: Johannes Thumshirn <Johannes.thumshirn@wdc.com> > Reviewed-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com>
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 0bc81b340295..a2de5c05f97c 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -2770,20 +2770,14 @@ struct btrfs_data_container *init_data_container(u32 total_bytes) size_t alloc_bytes; alloc_bytes = max_t(size_t, total_bytes, sizeof(*data)); - data = kvmalloc(alloc_bytes, GFP_KERNEL); + data = kvzalloc(alloc_bytes, GFP_KERNEL); if (!data) return ERR_PTR(-ENOMEM); - if (total_bytes >= sizeof(*data)) { + if (total_bytes >= sizeof(*data)) data->bytes_left = total_bytes - sizeof(*data); - data->bytes_missing = 0; - } else { + else data->bytes_missing = sizeof(*data) - total_bytes; - data->bytes_left = 0; - } - - data->elem_cnt = 0; - data->elem_missed = 0; return data; }