btrfs/154: rename fails with EOVERFLOW when calculating item size during item key collision
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned | ||
Bionic |
Fix Released
|
Medium
|
Matthew Ruffell | ||
Focal |
Fix Released
|
Medium
|
Matthew Ruffell |
Bug Description
BugLink: https:/
[Impact]
xfstests btrfs/154 fails on both Bionic and Focal, leading to a kernel oops and the btrfs volume being forced readonly.
In btrfs, item key collision is allowed for some item types, namely dir item and inode references. When inserting items into the btree, there are two objects, the btrfs_item and the item data. These objects must fit within the btree nodesize.
When a hash collision occurs, and we call btrfs_search_slot() to place the objects in the tree, when btrfs_search_slot() reaches the leaf node, a check is performed to see if we need to split the leaf. The check is incorrect, returning that we need to split the leaf, since it thinks that both btrfs_item and the item data need to be inserted, when in reality, the item can be merged with the existing one and no new btrfs_item will be inserted.
split_leaf() will return EOVERFLOW from following code:
if (extend && data_size + btrfs_item_
sizeof(struct btrfs_item) > BTRFS_LEAF_
return -EOVERFLOW;
In the rename case, btrfs_check_
data_size = sizeof(*di) + name_len;
if (data_size + btrfs_item_
The two sizes reported from btrfs_check_
Kernel oops:
BTRFS: Transaction aborted (error -75)
WARNING: CPU: 0 PID: 2921 at /build/
CPU: 0 PID: 2921 Comm: python3 Not tainted 4.15.0-202-generic #213-Ubuntu
RIP: 0010:btrfs_
RSP: 0018:ffff9e6f41
RAX: 0000000000000000 RBX: ffff91a493f27b98 RCX: 0000000000000006
RDX: 0000000000000007 RSI: 0000000000000096 RDI: ffff91a4bfc1b4d0
RBP: ffff9e6f4183fdc0 R08: 00000000000002b4 R09: 0000000000000004
R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000236
R13: ffff91a493f56518 R14: ffff91a4b6b57b40 R15: ffff91a493f27b98
FS: 00007f604108174
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f6040fe84c8 CR3: 000000015c8ca005 CR4: 0000000000760ef0
PKRU: 55555554
Call Trace:
btrfs_
vfs_rename+
SyS_rename+
do_syscall_
entry_
Code: 0f ba a8 d0 cd 00 00 02 72 2b 41 83 f8 fb 0f 84 d9 00 00 00 44 89 c6 48 c7 c7 68 43 4b c0 44 89 55 80 44 89 45 98 e8 8f 5c a6 d0 <0f> 0b 44 8b 45 98 44 8b 55 80 44 89 55 80 44 89 c1 44 89 45 98
---[ end trace 9c6b87a19f4436f3 ]---
BTRFS: error (device vdd) in btrfs_rename:10217: errno=-75 unknown
BTRFS info (device vdd): forced readonly
[Testcase]
Start a fresh Bionic or Focal VM.
Attach two scratch disks, I used standard virtio disks with 3gb of storage each. These disks are /dev/vdc and /dev/vdd.
Compile xfstests:
$ sudo apt-get install acl attr automake bc dbench dump e2fsprogs fio gawk \
gcc git indent libacl1-dev libaio-dev libcap-dev libgdbm-dev libtool \
libtool-bin libuuid1 lvm2 make psmisc python3 quota sed \
uuid-dev uuid-runtime xfsprogs linux-headers-
$ sudo apt-get install f2fs-tools ocfs2-tools udftools xfsdump \
xfslibs-dev
$ git clone git://git.
$ cd xfstests-dev
$ make
$ sudo su
# mkdir /test
# mkdir /scratch
# mkfs.btrfs -f /dev/vdc
# cat << EOF >> ./local.config
export TEST_DEV=/dev/vdc
export TEST_DIR=/test
export SCRATCH_
export SCRATCH_
EOF
# ./check btrfs/154
btrfs/154 _check_dmesg: something found in dmesg (see /home/ubuntu/
- output mismatch (see /home/ubuntu/
--- tests/btrfs/154.out 2023-01-28 02:53:03.566450703 +0000
+++ /home/ubuntu/
@@ -1,2 +1,6 @@
QA output created by 154
+Traceback (most recent call last):
+ File "/home/
+ os.rename(srcpath, dstpath)
+OSError: [Errno 75] Value too large for defined data type: '/scratch/309' -> b'/scratch/
Ran: btrfs/154
Failures: btrfs/154
Failed 1 of 1 tests
If you examine dmesg, you will see the oops from the impact section.
If you install the test kernel from the below ppa:
https:/
The issue no longer occurs:
# ./check btrfs/154
Ran: btrfs/154
Passed all 1 tests
[Fix]
This was fixed in 5.11-rc3 by the below commit:
commit 9a664971569daf6
Author: ethanwu <email address hidden>
Date: Tue Dec 1 17:25:12 2020 +0800
Subject: btrfs: correctly calculate item size used when item key collision happens
Link: https:/
This cherry-picks to Focal, and required a small backport to Bionic, removing the hunk that contained comments explaining the parameters to btrfs_search_
[Where problems could occur]
Problems could occur when calculating the size required for btrfs_item and item data when hash collisions occur. Such collisions are rare in of itself, but possible if you have a large amount files or craft filenames to force collisions with the crc32 hash algorithm.
If a regression were to occur, it could cause more transactions to be aborted, and would likely result in the users volume being forced read only. They might not lose any existing data, but data being written might be lost.
CVE References
Changed in linux (Ubuntu): | |
status: | New → Fix Released |
Changed in linux (Ubuntu Bionic): | |
status: | New → In Progress |
Changed in linux (Ubuntu Focal): | |
status: | New → In Progress |
Changed in linux (Ubuntu Bionic): | |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Focal): | |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Bionic): | |
assignee: | nobody → Matthew Ruffell (mruffell) |
Changed in linux (Ubuntu Focal): | |
assignee: | nobody → Matthew Ruffell (mruffell) |
description: | updated |
tags: | added: sts |
description: | updated |
Changed in linux (Ubuntu Bionic): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Focal): | |
status: | In Progress → Fix Committed |
This bug is awaiting verification that the linux-azure- 4.15/4. 15.0-1162. 177 kernel in -proposed solves the problem. Please test the kernel and update this bug with the results. If the problem is solved, change the tag 'verification- needed- bionic' to 'verification- done-bionic' . If the problem still exists, change the tag 'verification- needed- bionic' to 'verification- failed- bionic' .
If verification is not done by 5 working days from today, this fix will be dropped from the source code, and this bug will be closed.
See https:/ /wiki.ubuntu. com/Testing/ EnableProposed for documentation how to enable and use -proposed. Thank you!