CVE-2023-54180

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
30/12/2025
Last modified:
31/12/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> btrfs: handle case when repair happens with dev-replace<br /> <br /> [BUG]<br /> There is a bug report that a BUG_ON() in btrfs_repair_io_failure()<br /> (originally repair_io_failure() in v6.0 kernel) got triggered when<br /> replacing a unreliable disk:<br /> <br /> BTRFS warning (device sda1): csum failed root 257 ino 2397453 off 39624704 csum 0xb0d18c75 expected csum 0x4dae9c5e mirror 3<br /> kernel BUG at fs/btrfs/extent_io.c:2380!<br /> invalid opcode: 0000 [#1] PREEMPT SMP NOPTI<br /> CPU: 9 PID: 3614331 Comm: kworker/u257:2 Tainted: G OE 6.0.0-5-amd64 #1 Debian 6.0.10-2<br /> Hardware name: Micro-Star International Co., Ltd. MS-7C60/TRX40 PRO WIFI (MS-7C60), BIOS 2.70 07/01/2021<br /> Workqueue: btrfs-endio btrfs_end_bio_work [btrfs]<br /> RIP: 0010:repair_io_failure+0x24a/0x260 [btrfs]<br /> Call Trace:<br /> <br /> clean_io_failure+0x14d/0x180 [btrfs]<br /> end_bio_extent_readpage+0x412/0x6e0 [btrfs]<br /> ? __switch_to+0x106/0x420<br /> process_one_work+0x1c7/0x380<br /> worker_thread+0x4d/0x380<br /> ? rescuer_thread+0x3a0/0x3a0<br /> kthread+0xe9/0x110<br /> ? kthread_complete_and_exit+0x20/0x20<br /> ret_from_fork+0x22/0x30<br /> <br /> [CAUSE]<br /> <br /> Before the BUG_ON(), we got some read errors from the replace target<br /> first, note the mirror number (3, which is beyond RAID1 duplication,<br /> thus it&amp;#39;s read from the replace target device).<br /> <br /> Then at the BUG_ON() location, we are trying to writeback the repaired<br /> sectors back the failed device.<br /> <br /> The check looks like this:<br /> <br /> ret = btrfs_map_block(fs_info, BTRFS_MAP_WRITE, logical,<br /> &amp;map_length, &amp;bioc, mirror_num);<br /> if (ret)<br /> goto out_counter_dec;<br /> BUG_ON(mirror_num != bioc-&gt;mirror_num);<br /> <br /> But inside btrfs_map_block(), we can modify bioc-&gt;mirror_num especially<br /> for dev-replace:<br /> <br /> if (dev_replace_is_ongoing &amp;&amp; mirror_num == map-&gt;num_stripes + 1 &amp;&amp;<br /> !need_full_stripe(op) &amp;&amp; dev_replace-&gt;tgtdev != NULL) {<br /> ret = get_extra_mirror_from_replace(fs_info, logical, *length,<br /> dev_replace-&gt;srcdev-&gt;devid,<br /> &amp;mirror_num,<br /> &amp;physical_to_patch_in_first_stripe);<br /> patch_the_first_stripe_for_dev_replace = 1;<br /> }<br /> <br /> Thus if we&amp;#39;re repairing the replace target device, we&amp;#39;re going to<br /> trigger that BUG_ON().<br /> <br /> But in reality, the read failure from the replace target device may be<br /> that, our replace hasn&amp;#39;t reached the range we&amp;#39;re reading, thus we&amp;#39;re<br /> reading garbage, but with replace running, the range would be properly<br /> filled later.<br /> <br /> Thus in that case, we don&amp;#39;t need to do anything but let the replace<br /> routine to handle it.<br /> <br /> [FIX]<br /> Instead of a BUG_ON(), just skip the repair if we&amp;#39;re repairing the<br /> device replace target device.

Impact