CVE-2021-46989
Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
28/02/2024
Last modified:
14/03/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
hfsplus: prevent corruption in shrinking truncate<br />
<br />
I believe there are some issues introduced by commit 31651c607151<br />
("hfsplus: avoid deadlock on file truncation")<br />
<br />
HFS+ has extent records which always contains 8 extents. In case the<br />
first extent record in catalog file gets full, new ones are allocated from<br />
extents overflow file.<br />
<br />
In case shrinking truncate happens to middle of an extent record which<br />
locates in extents overflow file, the logic in hfsplus_file_truncate() was<br />
changed so that call to hfs_brec_remove() is not guarded any more.<br />
<br />
Right action would be just freeing the extents that exceed the new size<br />
inside extent record by calling hfsplus_free_extents(), and then check if<br />
the whole extent record should be removed. However since the guard<br />
(blk_cnt > start) is now after the call to hfs_brec_remove(), this has<br />
unfortunate effect that the last matching extent record is removed<br />
unconditionally.<br />
<br />
To reproduce this issue, create a file which has at least 10 extents, and<br />
then perform shrinking truncate into middle of the last extent record, so<br />
that the number of remaining extents is not under or divisible by 8. This<br />
causes the last extent record (8 extents) to be removed totally instead of<br />
truncating into middle of it. Thus this causes corruption, and lost data.<br />
<br />
Fix for this is simply checking if the new truncated end is below the<br />
start of this extent record, making it safe to remove the full extent<br />
record. However call to hfs_brec_remove() can&#39;t be moved to it&#39;s previous<br />
place since we&#39;re dropping ->tree_lock and it can cause a race condition<br />
and the cached info being invalidated possibly corrupting the node data.<br />
<br />
Another issue is related to this one. When entering into the block<br />
(blk_cnt > start) we are not holding the ->tree_lock. We break out from<br />
the loop not holding the lock, but hfs_find_exit() does unlock it. Not<br />
sure if it&#39;s possible for someone else to take the lock under our feet,<br />
but it can cause hard to debug errors and premature unlocking. Even if<br />
there&#39;s no real risk of it, the locking should still always be kept in<br />
balance. Thus taking the lock now just before the check.
Impact
Base Score 3.x
5.50
Severity 3.x
MEDIUM
Vulnerable products and versions
| CPE | From | Up to |
|---|---|---|
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 4.19 (including) | 4.19.191 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 4.20 (including) | 5.4.120 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.5 (including) | 5.10.38 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.11 (including) | 5.11.22 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.12 (including) | 5.12.5 (excluding) |
| cpe:2.3:o:linux:linux_kernel:5.13:rc1:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page
References to Advisories, Solutions, and Tools
- https://git.kernel.org/stable/c/52dde855663e5db824af51db39b5757d2ef3e28a
- https://git.kernel.org/stable/c/97314e45aa1223a42d60256a62c5d9af54baf446
- https://git.kernel.org/stable/c/adbd8a2a8cc05d9e501f93e5c95c59307874cc99
- https://git.kernel.org/stable/c/c3187cf32216313fb316084efac4dab3a8459b1d
- https://git.kernel.org/stable/c/c451a6bafb5f422197d31536f82116aed132b72c
- https://git.kernel.org/stable/c/c477f62db1a0c0ecaa60a29713006ceeeb04b685
- https://git.kernel.org/stable/c/52dde855663e5db824af51db39b5757d2ef3e28a
- https://git.kernel.org/stable/c/97314e45aa1223a42d60256a62c5d9af54baf446
- https://git.kernel.org/stable/c/adbd8a2a8cc05d9e501f93e5c95c59307874cc99
- https://git.kernel.org/stable/c/c3187cf32216313fb316084efac4dab3a8459b1d
- https://git.kernel.org/stable/c/c451a6bafb5f422197d31536f82116aed132b72c
- https://git.kernel.org/stable/c/c477f62db1a0c0ecaa60a29713006ceeeb04b685



