Lucene search

K
cve416baaa9-dc9f-4396-8d5f-8c081fb06d67CVE-2021-47072
HistoryMar 01, 2024 - 10:15 p.m.

CVE-2021-47072

2024-03-0122:15:47
416baaa9-dc9f-4396-8d5f-8c081fb06d67
web.nvd.nist.gov
662
cve
linux
kernel
btrfs
vulnerability
security
fix
log
inode
dentry
directory
permission
sync
fsync

6.5 Medium

AI Score

Confidence

Low

0.0004 Low

EPSS

Percentile

9.1%

In the Linux kernel, the following vulnerability has been resolved:

btrfs: fix removed dentries still existing after log is synced

When we move one inode from one directory to another and both the inode
and its previous parent directory were logged before, we are not supposed
to have the dentry for the old parent if we have a power failure after the
log is synced. Only the new dentry is supposed to exist.

Generally this works correctly, however there is a scenario where this is
not currently working, because the old parent of the file/directory that
was moved is not authoritative for a range that includes the dir index and
dir item keys of the old dentry. This case is better explained with the
following example and reproducer:

The test requires a very specific layout of keys and items in the

fs/subvolume btree to trigger the bug. So we want to make sure that

on whatever platform we are, we have the same leaf/node size.

Currently in btrfs the node/leaf size can not be smaller than the page

size (but it can be greater than the page size). So use the largest

supported node/leaf size (64K).

$ mkfs.btrfs -f -n 65536 /dev/sdc
$ mount /dev/sdc /mnt

“testdir” is inode 257.

$ mkdir /mnt/testdir
$ chmod 755 /mnt/testdir

Create several empty files to have the directory “testdir” with its

items spread over several leaves (7 in this case).

$ for ((i = 1; i <= 1200; i++)); do
echo -n > /mnt/testdir/file$i
done

Create our test directory “dira”, inode number 1458, which gets all

its items in leaf 7.

The BTRFS_DIR_ITEM_KEY item for inode 257 (“testdir”) that points to

the entry named “dira” is in leaf 2, while the BTRFS_DIR_INDEX_KEY

item that points to that entry is in leaf 3.

For this particular filesystem node size (64K), file count and file

names, we endup with the directory entry items from inode 257 in

leaves 2 and 3, as previously mentioned - what matters for triggering

the bug exercised by this test case is that those items are not placed

in leaf 1, they must be placed in a leaf different from the one

containing the inode item for inode 257.

The corresponding BTRFS_DIR_ITEM_KEY and BTRFS_DIR_INDEX_KEY items for

the parent inode (257) are the following:

item 460 key (257 DIR_ITEM 3724298081) itemoff 48344 itemsize 34

location key (1458 INODE_ITEM 0) type DIR

transid 6 data_len 0 name_len 4

name: dira

and:

item 771 key (257 DIR_INDEX 1202) itemoff 36673 itemsize 34

location key (1458 INODE_ITEM 0) type DIR

transid 6 data_len 0 name_len 4

name: dira

$ mkdir /mnt/testdir/dira

Make sure everything done so far is durably persisted.

$ sync

Now do a change to inode 257 (“testdir”) that does not result in

COWing leaves 2 and 3 - the leaves that contain the directory items

pointing to inode 1458 (directory “dira”).

Changing permissions, the owner/group, updating or adding a xattr,

etc, will not change (COW) leaves 2 and 3. So for the sake of

simplicity change the permissions of inode 257, which results in

updating its inode item and therefore change (COW) only leaf 1.

$ chmod 700 /mnt/testdir

Now fsync directory inode 257.

Since only the first leaf was changed/COWed, we log the inode item of

inode 257 and only the dentries found in the first leaf, all have a

key type of BTRFS_DIR_ITEM_KEY, and no keys of type

BTRFS_DIR_INDEX_KEY, because they sort after the former type and none

exist in the first leaf.

We also log 3 items that represent ranges for dir items and dir

indexes for which the log is authoritative:

1) a key of type BTRFS_DIR_LOG_ITEM_KEY, which indicates the log is

authoritative for all BTRFS_DIR_ITEM_KEY keys that have an offset

in the range [0, 2285968570] (the offset here is th

—truncated—

Affected configurations

Vulners
Node
linuxlinux_kernelRange5.125.12.7
OR
linuxlinux_kernelRange5.13.0
VendorProductVersionCPE
linuxlinux_kernel*cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
linuxlinux_kernel*cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*

CNA Affected

[
  {
    "product": "Linux",
    "vendor": "Linux",
    "defaultStatus": "unaffected",
    "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
    "programFiles": [
      "fs/btrfs/tree-log.c"
    ],
    "versions": [
      {
        "version": "64d6b281ba4d",
        "lessThan": "6d0924c5b742",
        "status": "affected",
        "versionType": "git"
      },
      {
        "version": "64d6b281ba4d",
        "lessThan": "54a40fc3a1da",
        "status": "affected",
        "versionType": "git"
      }
    ]
  },
  {
    "product": "Linux",
    "vendor": "Linux",
    "defaultStatus": "affected",
    "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
    "programFiles": [
      "fs/btrfs/tree-log.c"
    ],
    "versions": [
      {
        "version": "5.12",
        "status": "affected"
      },
      {
        "version": "0",
        "lessThan": "5.12",
        "status": "unaffected",
        "versionType": "custom"
      },
      {
        "version": "5.12.7",
        "lessThanOrEqual": "5.12.*",
        "status": "unaffected",
        "versionType": "custom"
      },
      {
        "version": "5.13",
        "lessThanOrEqual": "*",
        "status": "unaffected",
        "versionType": "original_commit_for_fix"
      }
    ]
  }
]

6.5 Medium

AI Score

Confidence

Low

0.0004 Low

EPSS

Percentile

9.1%