Instituto Nacional de ciberseguridad. Sección Incibe
Instituto Nacional de Ciberseguridad. Sección INCIBE-CERT

CVE-2023-54271

Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
30/12/2025
Última modificación:
30/12/2025

Descripción

*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> blk-cgroup: Fix NULL deref caused by blkg_policy_data being installed before init<br /> <br /> blk-iocost sometimes causes the following crash:<br /> <br /> BUG: kernel NULL pointer dereference, address: 00000000000000e0<br /> ...<br /> RIP: 0010:_raw_spin_lock+0x17/0x30<br /> Code: be 01 02 00 00 e8 79 38 39 ff 31 d2 89 d0 5d c3 0f 1f 00 0f 1f 44 00 00 55 48 89 e5 65 ff 05 48 d0 34 7e b9 01 00 00 00 31 c0 0f b1 0f 75 02 5d c3 89 c6 e8 ea 04 00 00 5d c3 0f 1f 84 00 00<br /> RSP: 0018:ffffc900023b3d40 EFLAGS: 00010046<br /> RAX: 0000000000000000 RBX: 00000000000000e0 RCX: 0000000000000001<br /> RDX: ffffc900023b3d20 RSI: ffffc900023b3cf0 RDI: 00000000000000e0<br /> RBP: ffffc900023b3d40 R08: ffffc900023b3c10 R09: 0000000000000003<br /> R10: 0000000000000064 R11: 000000000000000a R12: ffff888102337000<br /> R13: fffffffffffffff2 R14: ffff88810af408c8 R15: ffff8881070c3600<br /> FS: 00007faaaf364fc0(0000) GS:ffff88842fdc0000(0000) knlGS:0000000000000000<br /> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br /> CR2: 00000000000000e0 CR3: 00000001097b1000 CR4: 0000000000350ea0<br /> Call Trace:<br /> <br /> ioc_weight_write+0x13d/0x410<br /> cgroup_file_write+0x7a/0x130<br /> kernfs_fop_write_iter+0xf5/0x170<br /> vfs_write+0x298/0x370<br /> ksys_write+0x5f/0xb0<br /> __x64_sys_write+0x1b/0x20<br /> do_syscall_64+0x3d/0x80<br /> entry_SYSCALL_64_after_hwframe+0x46/0xb0<br /> <br /> This happens because iocg-&gt;ioc is NULL. The field is initialized by<br /> ioc_pd_init() and never cleared. The NULL deref is caused by<br /> blkcg_activate_policy() installing blkg_policy_data before initializing it.<br /> <br /> blkcg_activate_policy() was doing the following:<br /> <br /> 1. Allocate pd&amp;#39;s for all existing blkg&amp;#39;s and install them in blkg-&gt;pd[].<br /> 2. Initialize all pd&amp;#39;s.<br /> 3. Online all pd&amp;#39;s.<br /> <br /> blkcg_activate_policy() only grabs the queue_lock and may release and<br /> re-acquire the lock as allocation may need to sleep. ioc_weight_write()<br /> grabs blkcg-&gt;lock and iterates all its blkg&amp;#39;s. The two can race and if<br /> ioc_weight_write() runs during #1 or between #1 and #2, it can encounter a<br /> pd which is not initialized yet, leading to crash.<br /> <br /> The crash can be reproduced with the following script:<br /> <br /> #!/bin/bash<br /> <br /> echo +io &gt; /sys/fs/cgroup/cgroup.subtree_control<br /> systemd-run --unit touch-sda --scope dd if=/dev/sda of=/dev/null bs=1M count=1 iflag=direct<br /> echo 100 &gt; /sys/fs/cgroup/system.slice/io.weight<br /> bash -c "echo &amp;#39;8:0 enable=1&amp;#39; &gt; /sys/fs/cgroup/io.cost.qos" &amp;<br /> sleep .2<br /> echo 100 &gt; /sys/fs/cgroup/system.slice/io.weight<br /> <br /> with the following patch applied:<br /> <br /> &gt; diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c<br /> &gt; index fc49be622e05..38d671d5e10c 100644<br /> &gt; --- a/block/blk-cgroup.c<br /> &gt; +++ b/block/blk-cgroup.c<br /> &gt; @@ -1553,6 +1553,12 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)<br /> &gt; pd-&gt;online = false;<br /> &gt; }<br /> &gt;<br /> &gt; + if (system_state == SYSTEM_RUNNING) {<br /> &gt; + spin_unlock_irq(&amp;q-&gt;queue_lock);<br /> &gt; + ssleep(1);<br /> &gt; + spin_lock_irq(&amp;q-&gt;queue_lock);<br /> &gt; + }<br /> &gt; +<br /> &gt; /* all allocated, init in the same order */<br /> &gt; if (pol-&gt;pd_init_fn)<br /> &gt; list_for_each_entry_reverse(blkg, &amp;q-&gt;blkg_list, q_node)<br /> <br /> I don&amp;#39;t see a reason why all pd&amp;#39;s should be allocated, initialized and<br /> onlined together. The only ordering requirement is that parent blkgs to be<br /> initialized and onlined before children, which is guaranteed from the<br /> walking order. Let&amp;#39;s fix the bug by allocating, initializing and onlining pd<br /> for each blkg and holding blkcg-&gt;lock over initialization and onlining. This<br /> ensures that an installed blkg is always fully initialized and onlined<br /> removing the the race window.

Impacto