Message ID | 20240411221536.34798-1-bethany.jamison@canonical.com |
---|---|
Headers | show |
Series | CVE-2024-26792 | expand |
On 24/04/11 05:15PM, Bethany Jamison wrote: > [Impact] > > In the Linux kernel, the following vulnerability has been resolved: > > btrfs: fix double free of anonymous device after snapshot creation failure > > When creating a snapshot we may do a double free of an anonymous device > in case there's an error committing the transaction. The second free may > result in freeing an anonymous device number that was allocated by some > other subsystem in the kernel or another btrfs filesystem. > > The steps that lead to this: > > 1) At ioctl.c:create_snapshot() we allocate an anonymous device number > and assign it to pending_snapshot->anon_dev; > > 2) Then we call btrfs_commit_transaction() and end up at > transaction.c:create_pending_snapshot(); > > 3) There we call btrfs_get_new_fs_root() and pass it the anonymous device > number stored in pending_snapshot->anon_dev; > > 4) btrfs_get_new_fs_root() frees that anonymous device number because > btrfs_lookup_fs_root() returned a root - someone else did a lookup > of the new root already, which could some task doing backref walking; > > 5) After that some error happens in the transaction commit path, and at > ioctl.c:create_snapshot() we jump to the 'fail' label, and after > that we free again the same anonymous device number, which in the > meanwhile may have been reallocated somewhere else, because > pending_snapshot->anon_dev still has the same value as in step 1. > > Recently syzbot ran into this and reported the following trace: > > ------------[ cut here ]------------ > ida_free called for id=51 which is not allocated. > WARNING: CPU: 1 PID: 31038 at lib/idr.c:525 ida_free+0x370/0x420 > lib/idr.c:525 > Modules linked in: > CPU: 1 PID: 31038 Comm: syz-executor.2 Not tainted > 6.8.0-rc4-syzkaller-00410-gc02197fc9076 #0 > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS > Google 01/25/2024 > RIP: 0010:ida_free+0x370/0x420 lib/idr.c:525 > Code: 10 42 80 3c 28 (...) > RSP: 0018:ffffc90015a67300 EFLAGS: 00010246 > RAX: be5130472f5dd000 RBX: 0000000000000033 RCX: 0000000000040000 > RDX: ffffc90009a7a000 RSI: 000000000003ffff RDI: 0000000000040000 > RBP: ffffc90015a673f0 R08: ffffffff81577992 R09: 1ffff92002b4cdb4 > R10: dffffc0000000000 R11: fffff52002b4cdb5 R12: 0000000000000246 > R13: dffffc0000000000 R14: ffffffff8e256b80 R15: 0000000000000246 > FS: 00007fca3f4b46c0(0000) GS:ffff8880b9500000(0000) > knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 00007f167a17b978 CR3: 000000001ed26000 CR4: 0000000000350ef0 > Call Trace: > <TASK> > btrfs_get_root_ref+0xa48/0xaf0 fs/btrfs/disk-io.c:1346 > create_pending_snapshot+0xff2/0x2bc0 fs/btrfs/transaction.c:1837 > create_pending_snapshots+0x195/0x1d0 fs/btrfs/transaction.c:1931 > btrfs_commit_transaction+0xf1c/0x3740 fs/btrfs/transaction.c:2404 > create_snapshot+0x507/0x880 fs/btrfs/ioctl.c:848 > btrfs_mksubvol+0x5d0/0x750 fs/btrfs/ioctl.c:998 > btrfs_mksnapshot+0xb5/0xf0 fs/btrfs/ioctl.c:1044 > __btrfs_ioctl_snap_create+0x387/0x4b0 fs/btrfs/ioctl.c:1306 > btrfs_ioctl_snap_create_v2+0x1ca/0x400 fs/btrfs/ioctl.c:1393 > btrfs_ioctl+0xa74/0xd40 > vfs_ioctl fs/ioctl.c:51 [inline] > __do_sys_ioctl fs/ioctl.c:871 [inline] > __se_sys_ioctl+0xfe/0x170 fs/ioctl.c:857 > do_syscall_64+0xfb/0x240 > entry_SYSCALL_64_after_hwframe+0x6f/0x77 > RIP: 0033:0x7fca3e67dda9 > Code: 28 00 00 00 (...) > RSP: 002b:00007fca3f4b40c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 > RAX: ffffffffffffffda RBX: 00007fca3e7abf80 RCX: 00007fca3e67dda9 > RDX: 00000000200005c0 RSI: 0000000050009417 RDI: 0000000000000003 > RBP: 00007fca3e6ca47a R08: 0000000000000000 R09: 0000000000000000 > R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 > R13: 000000000000000b R14: 00007fca3e7abf80 R15: 00007fff6bf95658 > </TASK> > > Where we get an explicit message where we attempt to free an anonymous > device number that is not currently allocated. It happens in a different > code path from the example below, at btrfs_get_root_ref(), so this change > may not fix the case triggered by sy > ---truncated--- > > [Fix] > > Mantic: Clean cherry-pick from linux-6.6.y > Jammy: Backport - context conflict from neighboring line that didn't > affect the fix commit, I made the exact change as the fix > commit manually > Focal: not-affected > Bionic: not-affected > Xenial: not-affected > Trusty: not-affected > > [Test Case] > > Compile and boot tested. > > [Where problems could occur] > > This fix affects those who use btrfs when creating a snapshot, an > issue with this fix would be visable by corruption of the btrfs > or another file or subsystem. > > Filipe Manana (1): > btrfs: fix double free of anonymous device after snapshot creation > failure > > fs/btrfs/disk-io.c | 22 +++++++++++----------- > fs/btrfs/disk-io.h | 2 +- > fs/btrfs/ioctl.c | 2 +- > fs/btrfs/transaction.c | 2 +- > 4 files changed, 14 insertions(+), 14 deletions(-) Acked-by: Andrei Gherzan <andrei.gherzan@canonical.com>
On 4/11/24 4:15 PM, Bethany Jamison wrote: > [Impact] > > In the Linux kernel, the following vulnerability has been resolved: > > btrfs: fix double free of anonymous device after snapshot creation failure > > When creating a snapshot we may do a double free of an anonymous device > in case there's an error committing the transaction. The second free may > result in freeing an anonymous device number that was allocated by some > other subsystem in the kernel or another btrfs filesystem. > > The steps that lead to this: > > 1) At ioctl.c:create_snapshot() we allocate an anonymous device number > and assign it to pending_snapshot->anon_dev; > > 2) Then we call btrfs_commit_transaction() and end up at > transaction.c:create_pending_snapshot(); > > 3) There we call btrfs_get_new_fs_root() and pass it the anonymous device > number stored in pending_snapshot->anon_dev; > > 4) btrfs_get_new_fs_root() frees that anonymous device number because > btrfs_lookup_fs_root() returned a root - someone else did a lookup > of the new root already, which could some task doing backref walking; > > 5) After that some error happens in the transaction commit path, and at > ioctl.c:create_snapshot() we jump to the 'fail' label, and after > that we free again the same anonymous device number, which in the > meanwhile may have been reallocated somewhere else, because > pending_snapshot->anon_dev still has the same value as in step 1. > > Recently syzbot ran into this and reported the following trace: > > ------------[ cut here ]------------ > ida_free called for id=51 which is not allocated. > WARNING: CPU: 1 PID: 31038 at lib/idr.c:525 ida_free+0x370/0x420 > lib/idr.c:525 > Modules linked in: > CPU: 1 PID: 31038 Comm: syz-executor.2 Not tainted > 6.8.0-rc4-syzkaller-00410-gc02197fc9076 #0 > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS > Google 01/25/2024 > RIP: 0010:ida_free+0x370/0x420 lib/idr.c:525 > Code: 10 42 80 3c 28 (...) > RSP: 0018:ffffc90015a67300 EFLAGS: 00010246 > RAX: be5130472f5dd000 RBX: 0000000000000033 RCX: 0000000000040000 > RDX: ffffc90009a7a000 RSI: 000000000003ffff RDI: 0000000000040000 > RBP: ffffc90015a673f0 R08: ffffffff81577992 R09: 1ffff92002b4cdb4 > R10: dffffc0000000000 R11: fffff52002b4cdb5 R12: 0000000000000246 > R13: dffffc0000000000 R14: ffffffff8e256b80 R15: 0000000000000246 > FS: 00007fca3f4b46c0(0000) GS:ffff8880b9500000(0000) > knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 00007f167a17b978 CR3: 000000001ed26000 CR4: 0000000000350ef0 > Call Trace: > <TASK> > btrfs_get_root_ref+0xa48/0xaf0 fs/btrfs/disk-io.c:1346 > create_pending_snapshot+0xff2/0x2bc0 fs/btrfs/transaction.c:1837 > create_pending_snapshots+0x195/0x1d0 fs/btrfs/transaction.c:1931 > btrfs_commit_transaction+0xf1c/0x3740 fs/btrfs/transaction.c:2404 > create_snapshot+0x507/0x880 fs/btrfs/ioctl.c:848 > btrfs_mksubvol+0x5d0/0x750 fs/btrfs/ioctl.c:998 > btrfs_mksnapshot+0xb5/0xf0 fs/btrfs/ioctl.c:1044 > __btrfs_ioctl_snap_create+0x387/0x4b0 fs/btrfs/ioctl.c:1306 > btrfs_ioctl_snap_create_v2+0x1ca/0x400 fs/btrfs/ioctl.c:1393 > btrfs_ioctl+0xa74/0xd40 > vfs_ioctl fs/ioctl.c:51 [inline] > __do_sys_ioctl fs/ioctl.c:871 [inline] > __se_sys_ioctl+0xfe/0x170 fs/ioctl.c:857 > do_syscall_64+0xfb/0x240 > entry_SYSCALL_64_after_hwframe+0x6f/0x77 > RIP: 0033:0x7fca3e67dda9 > Code: 28 00 00 00 (...) > RSP: 002b:00007fca3f4b40c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 > RAX: ffffffffffffffda RBX: 00007fca3e7abf80 RCX: 00007fca3e67dda9 > RDX: 00000000200005c0 RSI: 0000000050009417 RDI: 0000000000000003 > RBP: 00007fca3e6ca47a R08: 0000000000000000 R09: 0000000000000000 > R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 > R13: 000000000000000b R14: 00007fca3e7abf80 R15: 00007fff6bf95658 > </TASK> > > Where we get an explicit message where we attempt to free an anonymous > device number that is not currently allocated. It happens in a different > code path from the example below, at btrfs_get_root_ref(), so this change > may not fix the case triggered by sy > ---truncated--- > > [Fix] > > Mantic: Clean cherry-pick from linux-6.6.y > Jammy: Backport - context conflict from neighboring line that didn't > affect the fix commit, I made the exact change as the fix > commit manually > Focal: not-affected > Bionic: not-affected > Xenial: not-affected > Trusty: not-affected > > [Test Case] > > Compile and boot tested. > > [Where problems could occur] > > This fix affects those who use btrfs when creating a snapshot, an > issue with this fix would be visable by corruption of the btrfs > or another file or subsystem. > > Filipe Manana (1): > btrfs: fix double free of anonymous device after snapshot creation > failure > > fs/btrfs/disk-io.c | 22 +++++++++++----------- > fs/btrfs/disk-io.h | 2 +- > fs/btrfs/ioctl.c | 2 +- > fs/btrfs/transaction.c | 2 +- > 4 files changed, 14 insertions(+), 14 deletions(-) > Acked-by: Tim Gardner <tim.gardner@canonical.com>
On 12/04/2024 00:15, Bethany Jamison wrote: > [Impact] > > In the Linux kernel, the following vulnerability has been resolved: > > btrfs: fix double free of anonymous device after snapshot creation failure > > When creating a snapshot we may do a double free of an anonymous device > in case there's an error committing the transaction. The second free may > result in freeing an anonymous device number that was allocated by some > other subsystem in the kernel or another btrfs filesystem. > > The steps that lead to this: > > 1) At ioctl.c:create_snapshot() we allocate an anonymous device number > and assign it to pending_snapshot->anon_dev; > > 2) Then we call btrfs_commit_transaction() and end up at > transaction.c:create_pending_snapshot(); > > 3) There we call btrfs_get_new_fs_root() and pass it the anonymous device > number stored in pending_snapshot->anon_dev; > > 4) btrfs_get_new_fs_root() frees that anonymous device number because > btrfs_lookup_fs_root() returned a root - someone else did a lookup > of the new root already, which could some task doing backref walking; > > 5) After that some error happens in the transaction commit path, and at > ioctl.c:create_snapshot() we jump to the 'fail' label, and after > that we free again the same anonymous device number, which in the > meanwhile may have been reallocated somewhere else, because > pending_snapshot->anon_dev still has the same value as in step 1. > > Recently syzbot ran into this and reported the following trace: > > ------------[ cut here ]------------ > ida_free called for id=51 which is not allocated. > WARNING: CPU: 1 PID: 31038 at lib/idr.c:525 ida_free+0x370/0x420 > lib/idr.c:525 > Modules linked in: > CPU: 1 PID: 31038 Comm: syz-executor.2 Not tainted > 6.8.0-rc4-syzkaller-00410-gc02197fc9076 #0 > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS > Google 01/25/2024 > RIP: 0010:ida_free+0x370/0x420 lib/idr.c:525 > Code: 10 42 80 3c 28 (...) > RSP: 0018:ffffc90015a67300 EFLAGS: 00010246 > RAX: be5130472f5dd000 RBX: 0000000000000033 RCX: 0000000000040000 > RDX: ffffc90009a7a000 RSI: 000000000003ffff RDI: 0000000000040000 > RBP: ffffc90015a673f0 R08: ffffffff81577992 R09: 1ffff92002b4cdb4 > R10: dffffc0000000000 R11: fffff52002b4cdb5 R12: 0000000000000246 > R13: dffffc0000000000 R14: ffffffff8e256b80 R15: 0000000000000246 > FS: 00007fca3f4b46c0(0000) GS:ffff8880b9500000(0000) > knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 00007f167a17b978 CR3: 000000001ed26000 CR4: 0000000000350ef0 > Call Trace: > <TASK> > btrfs_get_root_ref+0xa48/0xaf0 fs/btrfs/disk-io.c:1346 > create_pending_snapshot+0xff2/0x2bc0 fs/btrfs/transaction.c:1837 > create_pending_snapshots+0x195/0x1d0 fs/btrfs/transaction.c:1931 > btrfs_commit_transaction+0xf1c/0x3740 fs/btrfs/transaction.c:2404 > create_snapshot+0x507/0x880 fs/btrfs/ioctl.c:848 > btrfs_mksubvol+0x5d0/0x750 fs/btrfs/ioctl.c:998 > btrfs_mksnapshot+0xb5/0xf0 fs/btrfs/ioctl.c:1044 > __btrfs_ioctl_snap_create+0x387/0x4b0 fs/btrfs/ioctl.c:1306 > btrfs_ioctl_snap_create_v2+0x1ca/0x400 fs/btrfs/ioctl.c:1393 > btrfs_ioctl+0xa74/0xd40 > vfs_ioctl fs/ioctl.c:51 [inline] > __do_sys_ioctl fs/ioctl.c:871 [inline] > __se_sys_ioctl+0xfe/0x170 fs/ioctl.c:857 > do_syscall_64+0xfb/0x240 > entry_SYSCALL_64_after_hwframe+0x6f/0x77 > RIP: 0033:0x7fca3e67dda9 > Code: 28 00 00 00 (...) > RSP: 002b:00007fca3f4b40c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 > RAX: ffffffffffffffda RBX: 00007fca3e7abf80 RCX: 00007fca3e67dda9 > RDX: 00000000200005c0 RSI: 0000000050009417 RDI: 0000000000000003 > RBP: 00007fca3e6ca47a R08: 0000000000000000 R09: 0000000000000000 > R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 > R13: 000000000000000b R14: 00007fca3e7abf80 R15: 00007fff6bf95658 > </TASK> > > Where we get an explicit message where we attempt to free an anonymous > device number that is not currently allocated. It happens in a different > code path from the example below, at btrfs_get_root_ref(), so this change > may not fix the case triggered by sy > ---truncated--- > > [Fix] > > Mantic: Clean cherry-pick from linux-6.6.y > Jammy: Backport - context conflict from neighboring line that didn't > affect the fix commit, I made the exact change as the fix > commit manually > Focal: not-affected > Bionic: not-affected > Xenial: not-affected > Trusty: not-affected > > [Test Case] > > Compile and boot tested. > > [Where problems could occur] > > This fix affects those who use btrfs when creating a snapshot, an > issue with this fix would be visable by corruption of the btrfs > or another file or subsystem. > > Filipe Manana (1): > btrfs: fix double free of anonymous device after snapshot creation > failure > > fs/btrfs/disk-io.c | 22 +++++++++++----------- > fs/btrfs/disk-io.h | 2 +- > fs/btrfs/ioctl.c | 2 +- > fs/btrfs/transaction.c | 2 +- > 4 files changed, 14 insertions(+), 14 deletions(-) > Applied to mantic, jammy master-next branches. Thanks!