| 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-35784: btrfs: fix deadlock with fiemap and extent locking |
| |
| Description |
| =========== |
| |
| In the Linux kernel, the following vulnerability has been resolved: |
| |
| btrfs: fix deadlock with fiemap and extent locking |
| |
| While working on the patchset to remove extent locking I got a lockdep |
| splat with fiemap and pagefaulting with my new extent lock replacement |
| lock. |
| |
| This deadlock exists with our normal code, we just don't have lockdep |
| annotations with the extent locking so we've never noticed it. |
| |
| Since we're copying the fiemap extent to user space on every iteration |
| we have the chance of pagefaulting. Because we hold the extent lock for |
| the entire range we could mkwrite into a range in the file that we have |
| mmap'ed. This would deadlock with the following stack trace |
| |
| [<0>] lock_extent+0x28d/0x2f0 |
| [<0>] btrfs_page_mkwrite+0x273/0x8a0 |
| [<0>] do_page_mkwrite+0x50/0xb0 |
| [<0>] do_fault+0xc1/0x7b0 |
| [<0>] __handle_mm_fault+0x2fa/0x460 |
| [<0>] handle_mm_fault+0xa4/0x330 |
| [<0>] do_user_addr_fault+0x1f4/0x800 |
| [<0>] exc_page_fault+0x7c/0x1e0 |
| [<0>] asm_exc_page_fault+0x26/0x30 |
| [<0>] rep_movs_alternative+0x33/0x70 |
| [<0>] _copy_to_user+0x49/0x70 |
| [<0>] fiemap_fill_next_extent+0xc8/0x120 |
| [<0>] emit_fiemap_extent+0x4d/0xa0 |
| [<0>] extent_fiemap+0x7f8/0xad0 |
| [<0>] btrfs_fiemap+0x49/0x80 |
| [<0>] __x64_sys_ioctl+0x3e1/0xb50 |
| [<0>] do_syscall_64+0x94/0x1a0 |
| [<0>] entry_SYSCALL_64_after_hwframe+0x6e/0x76 |
| |
| I wrote an fstest to reproduce this deadlock without my replacement lock |
| and verified that the deadlock exists with our existing locking. |
| |
| To fix this simply don't take the extent lock for the entire duration of |
| the fiemap. This is safe in general because we keep track of where we |
| are when we're searching the tree, so if an ordered extent updates in |
| the middle of our fiemap call we'll still emit the correct extents |
| because we know what offset we were on before. |
| |
| The only place we maintain the lock is searching delalloc. Since the |
| delalloc stuff can change during writeback we want to lock the extent |
| range so we have a consistent view of delalloc at the time we're |
| checking to see if we need to set the delalloc flag. |
| |
| With this patch applied we no longer deadlock with my testcase. |
| |
| The Linux kernel CVE team has assigned CVE-2024-35784 to this issue. |
| |
| |
| Affected and fixed versions |
| =========================== |
| |
| Fixed in 6.6.24 with commit ded566b4637f1b6b4c9ba74e7d0b8493e93f19cf |
| Fixed in 6.7.12 with commit 89bca7fe6382d61e88c67a0b0e7bce315986fb8b |
| Fixed in 6.8 with commit b0ad381fa7690244802aed119b478b4bdafc31dd |
| |
| 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-35784 |
| 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/extent_io.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/ded566b4637f1b6b4c9ba74e7d0b8493e93f19cf |
| https://git.kernel.org/stable/c/89bca7fe6382d61e88c67a0b0e7bce315986fb8b |
| https://git.kernel.org/stable/c/b0ad381fa7690244802aed119b478b4bdafc31dd |