| From bippy-5f407fcff5a0 Mon Sep 17 00:00:00 2001 |
| From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| To: <linux-cve-announce@vger.kernel.org> |
| Reply-to: <cve@kernel.org>, <linux-kernel@vger.kernel.org> |
| Subject: CVE-2024-26792: btrfs: fix double free of anonymous device after snapshot creation failure |
| |
| Description |
| =========== |
| |
| 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 syzbot. |
| |
| To fix at least the code path from the example above, change |
| btrfs_get_root_ref() and its callers to receive a dev_t pointer argument |
| for the anonymous device number, so that in case it frees the number, it |
| also resets it to 0, so that up in the call chain we don't attempt to do |
| the double free. |
| |
| The Linux kernel CVE team has assigned CVE-2024-26792 to this issue. |
| |
| |
| Affected and fixed versions |
| =========================== |
| |
| Issue introduced in 6.1.79 with commit 66b317a2fc45b2ef66527ee3f8fa08fb5beab88d and fixed in 6.1.81 with commit c34adc20b91a8e55e048b18d63f4f4ae003ecf8f |
| Issue introduced in 6.6.18 with commit 833775656d447c545133a744a0ed1e189ce61430 and fixed in 6.6.21 with commit eb3441093aad251418921246fc3b224fd1575701 |
| Issue introduced in 6.7.6 with commit 5a172344bfdabb46458e03708735d7b1a918c468 and fixed in 6.7.9 with commit c8ab7521665bd0f8bc4a900244d1d5a7095cc3b9 |
| Issue introduced in 5.10.210 with commit 3f5d47eb163bceb1b9e613c9003bae5fefc0046f |
| Issue introduced in 5.15.149 with commit e31546b0f34af21738c4ceac47d662c00ee6382f |
| |
| Please see https://www.kernel.org for a full list of currently supported |
| kernel versions by the kernel community. |
| |
| Unaffected versions might change over time as fixes are backported to |
| older supported kernel versions. The official CVE entry at |
| https://cve.org/CVERecord/?id=CVE-2024-26792 |
| will be updated if fixes are backported, please check that for the most |
| up to date information about this issue. |
| |
| |
| Affected files |
| ============== |
| |
| The file(s) affected by this issue are: |
| fs/btrfs/disk-io.c |
| fs/btrfs/disk-io.h |
| fs/btrfs/ioctl.c |
| fs/btrfs/transaction.c |
| |
| |
| Mitigation |
| ========== |
| |
| The Linux kernel CVE team recommends that you update to the latest |
| stable kernel version for this, and many other bugfixes. Individual |
| changes are never tested alone, but rather are part of a larger kernel |
| release. Cherry-picking individual commits is not recommended or |
| supported by the Linux kernel community at all. If however, updating to |
| the latest release is impossible, the individual changes to resolve this |
| issue can be found at these commits: |
| https://git.kernel.org/stable/c/c34adc20b91a8e55e048b18d63f4f4ae003ecf8f |
| https://git.kernel.org/stable/c/eb3441093aad251418921246fc3b224fd1575701 |
| https://git.kernel.org/stable/c/c8ab7521665bd0f8bc4a900244d1d5a7095cc3b9 |
| https://git.kernel.org/stable/c/e2b54eaf28df0c978626c9736b94f003b523b451 |