CVE-2021-47072

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
01/03/2024
Last modified:
09/01/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> btrfs: fix removed dentries still existing after log is synced<br /> <br /> When we move one inode from one directory to another and both the inode<br /> and its previous parent directory were logged before, we are not supposed<br /> to have the dentry for the old parent if we have a power failure after the<br /> log is synced. Only the new dentry is supposed to exist.<br /> <br /> Generally this works correctly, however there is a scenario where this is<br /> not currently working, because the old parent of the file/directory that<br /> was moved is not authoritative for a range that includes the dir index and<br /> dir item keys of the old dentry. This case is better explained with the<br /> following example and reproducer:<br /> <br /> # The test requires a very specific layout of keys and items in the<br /> # fs/subvolume btree to trigger the bug. So we want to make sure that<br /> # on whatever platform we are, we have the same leaf/node size.<br /> #<br /> # Currently in btrfs the node/leaf size can not be smaller than the page<br /> # size (but it can be greater than the page size). So use the largest<br /> # supported node/leaf size (64K).<br /> <br /> $ mkfs.btrfs -f -n 65536 /dev/sdc<br /> $ mount /dev/sdc /mnt<br /> <br /> # "testdir" is inode 257.<br /> $ mkdir /mnt/testdir<br /> $ chmod 755 /mnt/testdir<br /> <br /> # Create several empty files to have the directory "testdir" with its<br /> # items spread over several leaves (7 in this case).<br /> $ for ((i = 1; i /mnt/testdir/file$i<br /> done<br /> <br /> # Create our test directory "dira", inode number 1458, which gets all<br /> # its items in leaf 7.<br /> #<br /> # The BTRFS_DIR_ITEM_KEY item for inode 257 ("testdir") that points to<br /> # the entry named "dira" is in leaf 2, while the BTRFS_DIR_INDEX_KEY<br /> # item that points to that entry is in leaf 3.<br /> #<br /> # For this particular filesystem node size (64K), file count and file<br /> # names, we endup with the directory entry items from inode 257 in<br /> # leaves 2 and 3, as previously mentioned - what matters for triggering<br /> # the bug exercised by this test case is that those items are not placed<br /> # in leaf 1, they must be placed in a leaf different from the one<br /> # containing the inode item for inode 257.<br /> #<br /> # The corresponding BTRFS_DIR_ITEM_KEY and BTRFS_DIR_INDEX_KEY items for<br /> # the parent inode (257) are the following:<br /> #<br /> # item 460 key (257 DIR_ITEM 3724298081) itemoff 48344 itemsize 34<br /> # location key (1458 INODE_ITEM 0) type DIR<br /> # transid 6 data_len 0 name_len 4<br /> # name: dira<br /> #<br /> # and:<br /> #<br /> # item 771 key (257 DIR_INDEX 1202) itemoff 36673 itemsize 34<br /> # location key (1458 INODE_ITEM 0) type DIR<br /> # transid 6 data_len 0 name_len 4<br /> # name: dira<br /> <br /> $ mkdir /mnt/testdir/dira<br /> <br /> # Make sure everything done so far is durably persisted.<br /> $ sync<br /> <br /> # Now do a change to inode 257 ("testdir") that does not result in<br /> # COWing leaves 2 and 3 - the leaves that contain the directory items<br /> # pointing to inode 1458 (directory "dira").<br /> #<br /> # Changing permissions, the owner/group, updating or adding a xattr,<br /> # etc, will not change (COW) leaves 2 and 3. So for the sake of<br /> # simplicity change the permissions of inode 257, which results in<br /> # updating its inode item and therefore change (COW) only leaf 1.<br /> <br /> $ chmod 700 /mnt/testdir<br /> <br /> # Now fsync directory inode 257.<br /> #<br /> # Since only the first leaf was changed/COWed, we log the inode item of<br /> # inode 257 and only the dentries found in the first leaf, all have a<br /> # key type of BTRFS_DIR_ITEM_KEY, and no keys of type<br /> # BTRFS_DIR_INDEX_KEY, because they sort after the former type and none<br /> # exist in the first leaf.<br /> #<br /> # We also log 3 items that represent ranges for dir items and dir<br /> # indexes for which the log is authoritative:<br /> #<br /> # 1) a key of type BTRFS_DIR_LOG_ITEM_KEY, which indicates the log is<br /> # authoritative for all BTRFS_DIR_ITEM_KEY keys that have an offset<br /> # in the range [0, 2285968570] (the offset here is th<br /> ---truncated---

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.12 (including) 5.12.7 (excluding)
cpe:2.3:o:linux:linux_kernel:5.13:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc2:*:*:*:*:*:*