All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] btrfs: drop path before copying root refs to userspace
@ 2022-11-07 16:44 Josef Bacik
  2022-11-08  8:41 ` Anand Jain
  2022-11-08 14:25 ` David Sterba
  0 siblings, 2 replies; 3+ messages in thread
From: Josef Bacik @ 2022-11-07 16:44 UTC (permalink / raw)
  To: linux-btrfs, kernel-team; +Cc: syzbot+4ef9e52e464c6ff47d9d

Syzbot reported the following lockdep splat

======================================================
WARNING: possible circular locking dependency detected
6.0.0-rc7-syzkaller-18095-gbbed346d5a96 #0 Not tainted
------------------------------------------------------
syz-executor307/3029 is trying to acquire lock:
ffff0000c02525d8 (&mm->mmap_lock){++++}-{3:3}, at: __might_fault+0x54/0xb4 mm/memory.c:5576

but task is already holding lock:
ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock fs/btrfs/locking.c:134 [inline]
ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_tree_read_lock fs/btrfs/locking.c:140 [inline]
ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_read_lock_root_node+0x13c/0x1c0 fs/btrfs/locking.c:279

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #3 (btrfs-root-00){++++}-{3:3}:
       down_read_nested+0x64/0x84 kernel/locking/rwsem.c:1624
       __btrfs_tree_read_lock fs/btrfs/locking.c:134 [inline]
       btrfs_tree_read_lock fs/btrfs/locking.c:140 [inline]
       btrfs_read_lock_root_node+0x13c/0x1c0 fs/btrfs/locking.c:279
       btrfs_search_slot_get_root+0x74/0x338 fs/btrfs/ctree.c:1637
       btrfs_search_slot+0x1b0/0xfd8 fs/btrfs/ctree.c:1944
       btrfs_update_root+0x6c/0x5a0 fs/btrfs/root-tree.c:132
       commit_fs_roots+0x1f0/0x33c fs/btrfs/transaction.c:1459
       btrfs_commit_transaction+0x89c/0x12d8 fs/btrfs/transaction.c:2343
       flush_space+0x66c/0x738 fs/btrfs/space-info.c:786
       btrfs_async_reclaim_metadata_space+0x43c/0x4e0 fs/btrfs/space-info.c:1059
       process_one_work+0x2d8/0x504 kernel/workqueue.c:2289
       worker_thread+0x340/0x610 kernel/workqueue.c:2436
       kthread+0x12c/0x158 kernel/kthread.c:376
       ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860

-> #2 (&fs_info->reloc_mutex){+.+.}-{3:3}:
       __mutex_lock_common+0xd4/0xca8 kernel/locking/mutex.c:603
       __mutex_lock kernel/locking/mutex.c:747 [inline]
       mutex_lock_nested+0x38/0x44 kernel/locking/mutex.c:799
       btrfs_record_root_in_trans fs/btrfs/transaction.c:516 [inline]
       start_transaction+0x248/0x944 fs/btrfs/transaction.c:752
       btrfs_start_transaction+0x34/0x44 fs/btrfs/transaction.c:781
       btrfs_create_common+0xf0/0x1b4 fs/btrfs/inode.c:6651
       btrfs_create+0x8c/0xb0 fs/btrfs/inode.c:6697
       lookup_open fs/namei.c:3413 [inline]
       open_last_lookups fs/namei.c:3481 [inline]
       path_openat+0x804/0x11c4 fs/namei.c:3688
       do_filp_open+0xdc/0x1b8 fs/namei.c:3718
       do_sys_openat2+0xb8/0x22c fs/open.c:1313
       do_sys_open fs/open.c:1329 [inline]
       __do_sys_openat fs/open.c:1345 [inline]
       __se_sys_openat fs/open.c:1340 [inline]
       __arm64_sys_openat+0xb0/0xe0 fs/open.c:1340
       __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
       invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
       el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
       do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
       el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
       el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
       el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581

-> #1 (sb_internal#2){.+.+}-{0:0}:
       percpu_down_read include/linux/percpu-rwsem.h:51 [inline]
       __sb_start_write include/linux/fs.h:1826 [inline]
       sb_start_intwrite include/linux/fs.h:1948 [inline]
       start_transaction+0x360/0x944 fs/btrfs/transaction.c:683
       btrfs_join_transaction+0x30/0x40 fs/btrfs/transaction.c:795
       btrfs_dirty_inode+0x50/0x140 fs/btrfs/inode.c:6103
       btrfs_update_time+0x1c0/0x1e8 fs/btrfs/inode.c:6145
       inode_update_time fs/inode.c:1872 [inline]
       touch_atime+0x1f0/0x4a8 fs/inode.c:1945
       file_accessed include/linux/fs.h:2516 [inline]
       btrfs_file_mmap+0x50/0x88 fs/btrfs/file.c:2407
       call_mmap include/linux/fs.h:2192 [inline]
       mmap_region+0x7fc/0xc14 mm/mmap.c:1752
       do_mmap+0x644/0x97c mm/mmap.c:1540
       vm_mmap_pgoff+0xe8/0x1d0 mm/util.c:552
       ksys_mmap_pgoff+0x1cc/0x278 mm/mmap.c:1586
       __do_sys_mmap arch/arm64/kernel/sys.c:28 [inline]
       __se_sys_mmap arch/arm64/kernel/sys.c:21 [inline]
       __arm64_sys_mmap+0x58/0x6c arch/arm64/kernel/sys.c:21
       __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
       invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
       el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
       do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
       el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
       el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
       el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581

-> #0 (&mm->mmap_lock){++++}-{3:3}:
       check_prev_add kernel/locking/lockdep.c:3095 [inline]
       check_prevs_add kernel/locking/lockdep.c:3214 [inline]
       validate_chain kernel/locking/lockdep.c:3829 [inline]
       __lock_acquire+0x1530/0x30a4 kernel/locking/lockdep.c:5053
       lock_acquire+0x100/0x1f8 kernel/locking/lockdep.c:5666
       __might_fault+0x7c/0xb4 mm/memory.c:5577
       _copy_to_user include/linux/uaccess.h:134 [inline]
       copy_to_user include/linux/uaccess.h:160 [inline]
       btrfs_ioctl_get_subvol_rootref+0x3a8/0x4bc fs/btrfs/ioctl.c:3203
       btrfs_ioctl+0xa08/0xa64 fs/btrfs/ioctl.c:5556
       vfs_ioctl fs/ioctl.c:51 [inline]
       __do_sys_ioctl fs/ioctl.c:870 [inline]
       __se_sys_ioctl fs/ioctl.c:856 [inline]
       __arm64_sys_ioctl+0xd0/0x140 fs/ioctl.c:856
       __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
       invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
       el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
       do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
       el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
       el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
       el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581

other info that might help us debug this:

Chain exists of:
  &mm->mmap_lock --> &fs_info->reloc_mutex --> btrfs-root-00

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(btrfs-root-00);
                               lock(&fs_info->reloc_mutex);
                               lock(btrfs-root-00);
  lock(&mm->mmap_lock);

 *** DEADLOCK ***

1 lock held by syz-executor307/3029:
 #0: ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock fs/btrfs/locking.c:134 [inline]
 #0: ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_tree_read_lock fs/btrfs/locking.c:140 [inline]
 #0: ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_read_lock_root_node+0x13c/0x1c0 fs/btrfs/locking.c:279

stack backtrace:
CPU: 0 PID: 3029 Comm: syz-executor307 Not tainted 6.0.0-rc7-syzkaller-18095-gbbed346d5a96 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/30/2022
Call trace:
 dump_backtrace+0x1c4/0x1f0 arch/arm64/kernel/stacktrace.c:156
 show_stack+0x2c/0x54 arch/arm64/kernel/stacktrace.c:163
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0x104/0x16c lib/dump_stack.c:106
 dump_stack+0x1c/0x58 lib/dump_stack.c:113
 print_circular_bug+0x2c4/0x2c8 kernel/locking/lockdep.c:2053
 check_noncircular+0x14c/0x154 kernel/locking/lockdep.c:2175
 check_prev_add kernel/locking/lockdep.c:3095 [inline]
 check_prevs_add kernel/locking/lockdep.c:3214 [inline]
 validate_chain kernel/locking/lockdep.c:3829 [inline]
 __lock_acquire+0x1530/0x30a4 kernel/locking/lockdep.c:5053
 lock_acquire+0x100/0x1f8 kernel/locking/lockdep.c:5666
 __might_fault+0x7c/0xb4 mm/memory.c:5577
 _copy_to_user include/linux/uaccess.h:134 [inline]
 copy_to_user include/linux/uaccess.h:160 [inline]
 btrfs_ioctl_get_subvol_rootref+0x3a8/0x4bc fs/btrfs/ioctl.c:3203
 btrfs_ioctl+0xa08/0xa64 fs/btrfs/ioctl.c:5556
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:870 [inline]
 __se_sys_ioctl fs/ioctl.c:856 [inline]
 __arm64_sys_ioctl+0xd0/0x140 fs/ioctl.c:856
 __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
 invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
 el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
 do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
 el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
 el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
 el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581

We do generally the right thing here, copying the references into a
temporary buffer, however we are still holding the path when we do
copy_to_user from the temporary buffer.  Fix this by free'ing the path
before we copy to user space.

Reported-by: syzbot+4ef9e52e464c6ff47d9d@syzkaller.appspotmail.com
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ioctl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 9c1cb5113178..306524554117 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2303,6 +2303,8 @@ static int btrfs_ioctl_get_subvol_rootref(struct btrfs_root *root,
 	}
 
 out:
+	btrfs_free_path(path);
+
 	if (!ret || ret == -EOVERFLOW) {
 		rootrefs->num_items = found;
 		/* update min_treeid for next search */
@@ -2314,7 +2316,6 @@ static int btrfs_ioctl_get_subvol_rootref(struct btrfs_root *root,
 	}
 
 	kfree(rootrefs);
-	btrfs_free_path(path);
 
 	return ret;
 }
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] btrfs: drop path before copying root refs to userspace
  2022-11-07 16:44 [PATCH] btrfs: drop path before copying root refs to userspace Josef Bacik
@ 2022-11-08  8:41 ` Anand Jain
  2022-11-08 14:25 ` David Sterba
  1 sibling, 0 replies; 3+ messages in thread
From: Anand Jain @ 2022-11-08  8:41 UTC (permalink / raw)
  To: Josef Bacik, linux-btrfs, kernel-team; +Cc: syzbot+4ef9e52e464c6ff47d9d

On 11/8/22 00:44, Josef Bacik wrote:
> Syzbot reported the following lockdep splat
> 
> ======================================================
> WARNING: possible circular locking dependency detected
> 6.0.0-rc7-syzkaller-18095-gbbed346d5a96 #0 Not tainted
> ------------------------------------------------------
> syz-executor307/3029 is trying to acquire lock:
> ffff0000c02525d8 (&mm->mmap_lock){++++}-{3:3}, at: __might_fault+0x54/0xb4 mm/memory.c:5576
> 
> but task is already holding lock:
> ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock fs/btrfs/locking.c:134 [inline]
> ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_tree_read_lock fs/btrfs/locking.c:140 [inline]
> ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_read_lock_root_node+0x13c/0x1c0 fs/btrfs/locking.c:279
> 
> which lock already depends on the new lock.
> 
> the existing dependency chain (in reverse order) is:
> 
> -> #3 (btrfs-root-00){++++}-{3:3}:
>         down_read_nested+0x64/0x84 kernel/locking/rwsem.c:1624
>         __btrfs_tree_read_lock fs/btrfs/locking.c:134 [inline]
>         btrfs_tree_read_lock fs/btrfs/locking.c:140 [inline]
>         btrfs_read_lock_root_node+0x13c/0x1c0 fs/btrfs/locking.c:279
>         btrfs_search_slot_get_root+0x74/0x338 fs/btrfs/ctree.c:1637
>         btrfs_search_slot+0x1b0/0xfd8 fs/btrfs/ctree.c:1944
>         btrfs_update_root+0x6c/0x5a0 fs/btrfs/root-tree.c:132
>         commit_fs_roots+0x1f0/0x33c fs/btrfs/transaction.c:1459
>         btrfs_commit_transaction+0x89c/0x12d8 fs/btrfs/transaction.c:2343
>         flush_space+0x66c/0x738 fs/btrfs/space-info.c:786
>         btrfs_async_reclaim_metadata_space+0x43c/0x4e0 fs/btrfs/space-info.c:1059
>         process_one_work+0x2d8/0x504 kernel/workqueue.c:2289
>         worker_thread+0x340/0x610 kernel/workqueue.c:2436
>         kthread+0x12c/0x158 kernel/kthread.c:376
>         ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860
> 
> -> #2 (&fs_info->reloc_mutex){+.+.}-{3:3}:
>         __mutex_lock_common+0xd4/0xca8 kernel/locking/mutex.c:603
>         __mutex_lock kernel/locking/mutex.c:747 [inline]
>         mutex_lock_nested+0x38/0x44 kernel/locking/mutex.c:799
>         btrfs_record_root_in_trans fs/btrfs/transaction.c:516 [inline]
>         start_transaction+0x248/0x944 fs/btrfs/transaction.c:752
>         btrfs_start_transaction+0x34/0x44 fs/btrfs/transaction.c:781
>         btrfs_create_common+0xf0/0x1b4 fs/btrfs/inode.c:6651
>         btrfs_create+0x8c/0xb0 fs/btrfs/inode.c:6697
>         lookup_open fs/namei.c:3413 [inline]
>         open_last_lookups fs/namei.c:3481 [inline]
>         path_openat+0x804/0x11c4 fs/namei.c:3688
>         do_filp_open+0xdc/0x1b8 fs/namei.c:3718
>         do_sys_openat2+0xb8/0x22c fs/open.c:1313
>         do_sys_open fs/open.c:1329 [inline]
>         __do_sys_openat fs/open.c:1345 [inline]
>         __se_sys_openat fs/open.c:1340 [inline]
>         __arm64_sys_openat+0xb0/0xe0 fs/open.c:1340
>         __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
>         invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
>         el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
>         do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
>         el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
>         el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
>         el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581
> 
> -> #1 (sb_internal#2){.+.+}-{0:0}:
>         percpu_down_read include/linux/percpu-rwsem.h:51 [inline]
>         __sb_start_write include/linux/fs.h:1826 [inline]
>         sb_start_intwrite include/linux/fs.h:1948 [inline]
>         start_transaction+0x360/0x944 fs/btrfs/transaction.c:683
>         btrfs_join_transaction+0x30/0x40 fs/btrfs/transaction.c:795
>         btrfs_dirty_inode+0x50/0x140 fs/btrfs/inode.c:6103
>         btrfs_update_time+0x1c0/0x1e8 fs/btrfs/inode.c:6145
>         inode_update_time fs/inode.c:1872 [inline]
>         touch_atime+0x1f0/0x4a8 fs/inode.c:1945
>         file_accessed include/linux/fs.h:2516 [inline]
>         btrfs_file_mmap+0x50/0x88 fs/btrfs/file.c:2407
>         call_mmap include/linux/fs.h:2192 [inline]
>         mmap_region+0x7fc/0xc14 mm/mmap.c:1752
>         do_mmap+0x644/0x97c mm/mmap.c:1540
>         vm_mmap_pgoff+0xe8/0x1d0 mm/util.c:552
>         ksys_mmap_pgoff+0x1cc/0x278 mm/mmap.c:1586
>         __do_sys_mmap arch/arm64/kernel/sys.c:28 [inline]
>         __se_sys_mmap arch/arm64/kernel/sys.c:21 [inline]
>         __arm64_sys_mmap+0x58/0x6c arch/arm64/kernel/sys.c:21
>         __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
>         invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
>         el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
>         do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
>         el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
>         el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
>         el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581
> 
> -> #0 (&mm->mmap_lock){++++}-{3:3}:
>         check_prev_add kernel/locking/lockdep.c:3095 [inline]
>         check_prevs_add kernel/locking/lockdep.c:3214 [inline]
>         validate_chain kernel/locking/lockdep.c:3829 [inline]
>         __lock_acquire+0x1530/0x30a4 kernel/locking/lockdep.c:5053
>         lock_acquire+0x100/0x1f8 kernel/locking/lockdep.c:5666
>         __might_fault+0x7c/0xb4 mm/memory.c:5577
>         _copy_to_user include/linux/uaccess.h:134 [inline]
>         copy_to_user include/linux/uaccess.h:160 [inline]
>         btrfs_ioctl_get_subvol_rootref+0x3a8/0x4bc fs/btrfs/ioctl.c:3203
>         btrfs_ioctl+0xa08/0xa64 fs/btrfs/ioctl.c:5556
>         vfs_ioctl fs/ioctl.c:51 [inline]
>         __do_sys_ioctl fs/ioctl.c:870 [inline]
>         __se_sys_ioctl fs/ioctl.c:856 [inline]
>         __arm64_sys_ioctl+0xd0/0x140 fs/ioctl.c:856
>         __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
>         invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
>         el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
>         do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
>         el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
>         el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
>         el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581
> 
> other info that might help us debug this:
> 
> Chain exists of:
>    &mm->mmap_lock --> &fs_info->reloc_mutex --> btrfs-root-00
> 
>   Possible unsafe locking scenario:
> 
>         CPU0                    CPU1
>         ----                    ----
>    lock(btrfs-root-00);
>                                 lock(&fs_info->reloc_mutex);
>                                 lock(btrfs-root-00);
>    lock(&mm->mmap_lock);
> 
>   *** DEADLOCK ***
> 
> 1 lock held by syz-executor307/3029:
>   #0: ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock fs/btrfs/locking.c:134 [inline]
>   #0: ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_tree_read_lock fs/btrfs/locking.c:140 [inline]
>   #0: ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_read_lock_root_node+0x13c/0x1c0 fs/btrfs/locking.c:279
> 
> stack backtrace:
> CPU: 0 PID: 3029 Comm: syz-executor307 Not tainted 6.0.0-rc7-syzkaller-18095-gbbed346d5a96 #0
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/30/2022
> Call trace:
>   dump_backtrace+0x1c4/0x1f0 arch/arm64/kernel/stacktrace.c:156
>   show_stack+0x2c/0x54 arch/arm64/kernel/stacktrace.c:163
>   __dump_stack lib/dump_stack.c:88 [inline]
>   dump_stack_lvl+0x104/0x16c lib/dump_stack.c:106
>   dump_stack+0x1c/0x58 lib/dump_stack.c:113
>   print_circular_bug+0x2c4/0x2c8 kernel/locking/lockdep.c:2053
>   check_noncircular+0x14c/0x154 kernel/locking/lockdep.c:2175
>   check_prev_add kernel/locking/lockdep.c:3095 [inline]
>   check_prevs_add kernel/locking/lockdep.c:3214 [inline]
>   validate_chain kernel/locking/lockdep.c:3829 [inline]
>   __lock_acquire+0x1530/0x30a4 kernel/locking/lockdep.c:5053
>   lock_acquire+0x100/0x1f8 kernel/locking/lockdep.c:5666
>   __might_fault+0x7c/0xb4 mm/memory.c:5577
>   _copy_to_user include/linux/uaccess.h:134 [inline]
>   copy_to_user include/linux/uaccess.h:160 [inline]
>   btrfs_ioctl_get_subvol_rootref+0x3a8/0x4bc fs/btrfs/ioctl.c:3203
>   btrfs_ioctl+0xa08/0xa64 fs/btrfs/ioctl.c:5556
>   vfs_ioctl fs/ioctl.c:51 [inline]
>   __do_sys_ioctl fs/ioctl.c:870 [inline]
>   __se_sys_ioctl fs/ioctl.c:856 [inline]
>   __arm64_sys_ioctl+0xd0/0x140 fs/ioctl.c:856
>   __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
>   invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
>   el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
>   do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
>   el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
>   el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
>   el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581
> 
> We do generally the right thing here, copying the references into a
> temporary buffer, however we are still holding the path when we do
> copy_to_user from the temporary buffer.  Fix this by free'ing the path
> before we copy to user space.
> 
> Reported-by: syzbot+4ef9e52e464c6ff47d9d@syzkaller.appspotmail.com
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>


Reviewed-by: Anand Jain <anand.jain@oracle.com>


> ---
>   fs/btrfs/ioctl.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index 9c1cb5113178..306524554117 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -2303,6 +2303,8 @@ static int btrfs_ioctl_get_subvol_rootref(struct btrfs_root *root,
>   	}
>   
>   out:
> +	btrfs_free_path(path);
> +
>   	if (!ret || ret == -EOVERFLOW) {
>   		rootrefs->num_items = found;
>   		/* update min_treeid for next search */
> @@ -2314,7 +2316,6 @@ static int btrfs_ioctl_get_subvol_rootref(struct btrfs_root *root,
>   	}
>   
>   	kfree(rootrefs);
> -	btrfs_free_path(path);
>   
>   	return ret;
>   }


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] btrfs: drop path before copying root refs to userspace
  2022-11-07 16:44 [PATCH] btrfs: drop path before copying root refs to userspace Josef Bacik
  2022-11-08  8:41 ` Anand Jain
@ 2022-11-08 14:25 ` David Sterba
  1 sibling, 0 replies; 3+ messages in thread
From: David Sterba @ 2022-11-08 14:25 UTC (permalink / raw)
  To: Josef Bacik; +Cc: linux-btrfs, kernel-team, syzbot+4ef9e52e464c6ff47d9d

On Mon, Nov 07, 2022 at 11:44:51AM -0500, Josef Bacik wrote:
> Syzbot reported the following lockdep splat
> 
> ======================================================
> WARNING: possible circular locking dependency detected
> 6.0.0-rc7-syzkaller-18095-gbbed346d5a96 #0 Not tainted
> ------------------------------------------------------
> syz-executor307/3029 is trying to acquire lock:
> ffff0000c02525d8 (&mm->mmap_lock){++++}-{3:3}, at: __might_fault+0x54/0xb4 mm/memory.c:5576
> 
> but task is already holding lock:
> ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock fs/btrfs/locking.c:134 [inline]
> ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_tree_read_lock fs/btrfs/locking.c:140 [inline]
> ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_read_lock_root_node+0x13c/0x1c0 fs/btrfs/locking.c:279
> 
> which lock already depends on the new lock.
> 
> the existing dependency chain (in reverse order) is:
> 
> -> #3 (btrfs-root-00){++++}-{3:3}:
>        down_read_nested+0x64/0x84 kernel/locking/rwsem.c:1624
>        __btrfs_tree_read_lock fs/btrfs/locking.c:134 [inline]
>        btrfs_tree_read_lock fs/btrfs/locking.c:140 [inline]
>        btrfs_read_lock_root_node+0x13c/0x1c0 fs/btrfs/locking.c:279
>        btrfs_search_slot_get_root+0x74/0x338 fs/btrfs/ctree.c:1637
>        btrfs_search_slot+0x1b0/0xfd8 fs/btrfs/ctree.c:1944
>        btrfs_update_root+0x6c/0x5a0 fs/btrfs/root-tree.c:132
>        commit_fs_roots+0x1f0/0x33c fs/btrfs/transaction.c:1459
>        btrfs_commit_transaction+0x89c/0x12d8 fs/btrfs/transaction.c:2343
>        flush_space+0x66c/0x738 fs/btrfs/space-info.c:786
>        btrfs_async_reclaim_metadata_space+0x43c/0x4e0 fs/btrfs/space-info.c:1059
>        process_one_work+0x2d8/0x504 kernel/workqueue.c:2289
>        worker_thread+0x340/0x610 kernel/workqueue.c:2436
>        kthread+0x12c/0x158 kernel/kthread.c:376
>        ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860
> 
> -> #2 (&fs_info->reloc_mutex){+.+.}-{3:3}:
>        __mutex_lock_common+0xd4/0xca8 kernel/locking/mutex.c:603
>        __mutex_lock kernel/locking/mutex.c:747 [inline]
>        mutex_lock_nested+0x38/0x44 kernel/locking/mutex.c:799
>        btrfs_record_root_in_trans fs/btrfs/transaction.c:516 [inline]
>        start_transaction+0x248/0x944 fs/btrfs/transaction.c:752
>        btrfs_start_transaction+0x34/0x44 fs/btrfs/transaction.c:781
>        btrfs_create_common+0xf0/0x1b4 fs/btrfs/inode.c:6651
>        btrfs_create+0x8c/0xb0 fs/btrfs/inode.c:6697
>        lookup_open fs/namei.c:3413 [inline]
>        open_last_lookups fs/namei.c:3481 [inline]
>        path_openat+0x804/0x11c4 fs/namei.c:3688
>        do_filp_open+0xdc/0x1b8 fs/namei.c:3718
>        do_sys_openat2+0xb8/0x22c fs/open.c:1313
>        do_sys_open fs/open.c:1329 [inline]
>        __do_sys_openat fs/open.c:1345 [inline]
>        __se_sys_openat fs/open.c:1340 [inline]
>        __arm64_sys_openat+0xb0/0xe0 fs/open.c:1340
>        __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
>        invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
>        el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
>        do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
>        el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
>        el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
>        el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581
> 
> -> #1 (sb_internal#2){.+.+}-{0:0}:
>        percpu_down_read include/linux/percpu-rwsem.h:51 [inline]
>        __sb_start_write include/linux/fs.h:1826 [inline]
>        sb_start_intwrite include/linux/fs.h:1948 [inline]
>        start_transaction+0x360/0x944 fs/btrfs/transaction.c:683
>        btrfs_join_transaction+0x30/0x40 fs/btrfs/transaction.c:795
>        btrfs_dirty_inode+0x50/0x140 fs/btrfs/inode.c:6103
>        btrfs_update_time+0x1c0/0x1e8 fs/btrfs/inode.c:6145
>        inode_update_time fs/inode.c:1872 [inline]
>        touch_atime+0x1f0/0x4a8 fs/inode.c:1945
>        file_accessed include/linux/fs.h:2516 [inline]
>        btrfs_file_mmap+0x50/0x88 fs/btrfs/file.c:2407
>        call_mmap include/linux/fs.h:2192 [inline]
>        mmap_region+0x7fc/0xc14 mm/mmap.c:1752
>        do_mmap+0x644/0x97c mm/mmap.c:1540
>        vm_mmap_pgoff+0xe8/0x1d0 mm/util.c:552
>        ksys_mmap_pgoff+0x1cc/0x278 mm/mmap.c:1586
>        __do_sys_mmap arch/arm64/kernel/sys.c:28 [inline]
>        __se_sys_mmap arch/arm64/kernel/sys.c:21 [inline]
>        __arm64_sys_mmap+0x58/0x6c arch/arm64/kernel/sys.c:21
>        __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
>        invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
>        el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
>        do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
>        el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
>        el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
>        el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581
> 
> -> #0 (&mm->mmap_lock){++++}-{3:3}:
>        check_prev_add kernel/locking/lockdep.c:3095 [inline]
>        check_prevs_add kernel/locking/lockdep.c:3214 [inline]
>        validate_chain kernel/locking/lockdep.c:3829 [inline]
>        __lock_acquire+0x1530/0x30a4 kernel/locking/lockdep.c:5053
>        lock_acquire+0x100/0x1f8 kernel/locking/lockdep.c:5666
>        __might_fault+0x7c/0xb4 mm/memory.c:5577
>        _copy_to_user include/linux/uaccess.h:134 [inline]
>        copy_to_user include/linux/uaccess.h:160 [inline]
>        btrfs_ioctl_get_subvol_rootref+0x3a8/0x4bc fs/btrfs/ioctl.c:3203
>        btrfs_ioctl+0xa08/0xa64 fs/btrfs/ioctl.c:5556
>        vfs_ioctl fs/ioctl.c:51 [inline]
>        __do_sys_ioctl fs/ioctl.c:870 [inline]
>        __se_sys_ioctl fs/ioctl.c:856 [inline]
>        __arm64_sys_ioctl+0xd0/0x140 fs/ioctl.c:856
>        __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
>        invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
>        el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
>        do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
>        el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
>        el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
>        el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581
> 
> other info that might help us debug this:
> 
> Chain exists of:
>   &mm->mmap_lock --> &fs_info->reloc_mutex --> btrfs-root-00
> 
>  Possible unsafe locking scenario:
> 
>        CPU0                    CPU1
>        ----                    ----
>   lock(btrfs-root-00);
>                                lock(&fs_info->reloc_mutex);
>                                lock(btrfs-root-00);
>   lock(&mm->mmap_lock);
> 
>  *** DEADLOCK ***
> 
> 1 lock held by syz-executor307/3029:
>  #0: ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock fs/btrfs/locking.c:134 [inline]
>  #0: ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_tree_read_lock fs/btrfs/locking.c:140 [inline]
>  #0: ffff0000c958a608 (btrfs-root-00){++++}-{3:3}, at: btrfs_read_lock_root_node+0x13c/0x1c0 fs/btrfs/locking.c:279
> 
> stack backtrace:
> CPU: 0 PID: 3029 Comm: syz-executor307 Not tainted 6.0.0-rc7-syzkaller-18095-gbbed346d5a96 #0
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/30/2022
> Call trace:
>  dump_backtrace+0x1c4/0x1f0 arch/arm64/kernel/stacktrace.c:156
>  show_stack+0x2c/0x54 arch/arm64/kernel/stacktrace.c:163
>  __dump_stack lib/dump_stack.c:88 [inline]
>  dump_stack_lvl+0x104/0x16c lib/dump_stack.c:106
>  dump_stack+0x1c/0x58 lib/dump_stack.c:113
>  print_circular_bug+0x2c4/0x2c8 kernel/locking/lockdep.c:2053
>  check_noncircular+0x14c/0x154 kernel/locking/lockdep.c:2175
>  check_prev_add kernel/locking/lockdep.c:3095 [inline]
>  check_prevs_add kernel/locking/lockdep.c:3214 [inline]
>  validate_chain kernel/locking/lockdep.c:3829 [inline]
>  __lock_acquire+0x1530/0x30a4 kernel/locking/lockdep.c:5053
>  lock_acquire+0x100/0x1f8 kernel/locking/lockdep.c:5666
>  __might_fault+0x7c/0xb4 mm/memory.c:5577
>  _copy_to_user include/linux/uaccess.h:134 [inline]
>  copy_to_user include/linux/uaccess.h:160 [inline]
>  btrfs_ioctl_get_subvol_rootref+0x3a8/0x4bc fs/btrfs/ioctl.c:3203
>  btrfs_ioctl+0xa08/0xa64 fs/btrfs/ioctl.c:5556
>  vfs_ioctl fs/ioctl.c:51 [inline]
>  __do_sys_ioctl fs/ioctl.c:870 [inline]
>  __se_sys_ioctl fs/ioctl.c:856 [inline]
>  __arm64_sys_ioctl+0xd0/0x140 fs/ioctl.c:856
>  __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
>  invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
>  el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
>  do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
>  el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
>  el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
>  el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581
> 
> We do generally the right thing here, copying the references into a
> temporary buffer, however we are still holding the path when we do
> copy_to_user from the temporary buffer.  Fix this by free'ing the path
> before we copy to user space.
> 
> Reported-by: syzbot+4ef9e52e464c6ff47d9d@syzkaller.appspotmail.com
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>

Added to misc-next, thanks.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-11-08 14:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-07 16:44 [PATCH] btrfs: drop path before copying root refs to userspace Josef Bacik
2022-11-08  8:41 ` Anand Jain
2022-11-08 14:25 ` David Sterba

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.