CVE-2023-54271 (GCVE-0-2023-54271)
Vulnerability from cvelistv5 – Published: 2025-12-30 12:16 – Updated: 2025-12-30 12:16
VLAI?
Title
blk-cgroup: Fix NULL deref caused by blkg_policy_data being installed before init
Summary
In the Linux kernel, the following vulnerability has been resolved:
blk-cgroup: Fix NULL deref caused by blkg_policy_data being installed before init
blk-iocost sometimes causes the following crash:
BUG: kernel NULL pointer dereference, address: 00000000000000e0
...
RIP: 0010:_raw_spin_lock+0x17/0x30
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 <f0> 0f b1 0f 75 02 5d c3 89 c6 e8 ea 04 00 00 5d c3 0f 1f 84 00 00
RSP: 0018:ffffc900023b3d40 EFLAGS: 00010046
RAX: 0000000000000000 RBX: 00000000000000e0 RCX: 0000000000000001
RDX: ffffc900023b3d20 RSI: ffffc900023b3cf0 RDI: 00000000000000e0
RBP: ffffc900023b3d40 R08: ffffc900023b3c10 R09: 0000000000000003
R10: 0000000000000064 R11: 000000000000000a R12: ffff888102337000
R13: fffffffffffffff2 R14: ffff88810af408c8 R15: ffff8881070c3600
FS: 00007faaaf364fc0(0000) GS:ffff88842fdc0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000000e0 CR3: 00000001097b1000 CR4: 0000000000350ea0
Call Trace:
<TASK>
ioc_weight_write+0x13d/0x410
cgroup_file_write+0x7a/0x130
kernfs_fop_write_iter+0xf5/0x170
vfs_write+0x298/0x370
ksys_write+0x5f/0xb0
__x64_sys_write+0x1b/0x20
do_syscall_64+0x3d/0x80
entry_SYSCALL_64_after_hwframe+0x46/0xb0
This happens because iocg->ioc is NULL. The field is initialized by
ioc_pd_init() and never cleared. The NULL deref is caused by
blkcg_activate_policy() installing blkg_policy_data before initializing it.
blkcg_activate_policy() was doing the following:
1. Allocate pd's for all existing blkg's and install them in blkg->pd[].
2. Initialize all pd's.
3. Online all pd's.
blkcg_activate_policy() only grabs the queue_lock and may release and
re-acquire the lock as allocation may need to sleep. ioc_weight_write()
grabs blkcg->lock and iterates all its blkg's. The two can race and if
ioc_weight_write() runs during #1 or between #1 and #2, it can encounter a
pd which is not initialized yet, leading to crash.
The crash can be reproduced with the following script:
#!/bin/bash
echo +io > /sys/fs/cgroup/cgroup.subtree_control
systemd-run --unit touch-sda --scope dd if=/dev/sda of=/dev/null bs=1M count=1 iflag=direct
echo 100 > /sys/fs/cgroup/system.slice/io.weight
bash -c "echo '8:0 enable=1' > /sys/fs/cgroup/io.cost.qos" &
sleep .2
echo 100 > /sys/fs/cgroup/system.slice/io.weight
with the following patch applied:
> diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
> index fc49be622e05..38d671d5e10c 100644
> --- a/block/blk-cgroup.c
> +++ b/block/blk-cgroup.c
> @@ -1553,6 +1553,12 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
> pd->online = false;
> }
>
> + if (system_state == SYSTEM_RUNNING) {
> + spin_unlock_irq(&q->queue_lock);
> + ssleep(1);
> + spin_lock_irq(&q->queue_lock);
> + }
> +
> /* all allocated, init in the same order */
> if (pol->pd_init_fn)
> list_for_each_entry_reverse(blkg, &q->blkg_list, q_node)
I don't see a reason why all pd's should be allocated, initialized and
onlined together. The only ordering requirement is that parent blkgs to be
initialized and onlined before children, which is guaranteed from the
walking order. Let's fix the bug by allocating, initializing and onlining pd
for each blkg and holding blkcg->lock over initialization and onlining. This
ensures that an installed blkg is always fully initialized and onlined
removing the the race window.
Severity ?
No CVSS data available.
Assigner
References
Impacted products
| Vendor | Product | Version | ||
|---|---|---|---|---|
| Linux | Linux |
Affected:
9d179b865449b351ad5cb76dbea480c9170d4a27 , < e39ef7880d1057b2ebcdb013405f4d84a257db23
(git)
Affected: 9d179b865449b351ad5cb76dbea480c9170d4a27 , < 7d63c6f9765339dcfc34b7365ced7c518012e4fe (git) Affected: 9d179b865449b351ad5cb76dbea480c9170d4a27 , < ec14a87ee1999b19d8b7ed0fa95fea80644624ae (git) |
||
{
"containers": {
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"product": "Linux",
"programFiles": [
"block/blk-cgroup.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"lessThan": "e39ef7880d1057b2ebcdb013405f4d84a257db23",
"status": "affected",
"version": "9d179b865449b351ad5cb76dbea480c9170d4a27",
"versionType": "git"
},
{
"lessThan": "7d63c6f9765339dcfc34b7365ced7c518012e4fe",
"status": "affected",
"version": "9d179b865449b351ad5cb76dbea480c9170d4a27",
"versionType": "git"
},
{
"lessThan": "ec14a87ee1999b19d8b7ed0fa95fea80644624ae",
"status": "affected",
"version": "9d179b865449b351ad5cb76dbea480c9170d4a27",
"versionType": "git"
}
]
},
{
"defaultStatus": "affected",
"product": "Linux",
"programFiles": [
"block/blk-cgroup.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"status": "affected",
"version": "5.4"
},
{
"lessThan": "5.4",
"status": "unaffected",
"version": "0",
"versionType": "semver"
},
{
"lessThanOrEqual": "6.4.*",
"status": "unaffected",
"version": "6.4.16",
"versionType": "semver"
},
{
"lessThanOrEqual": "6.5.*",
"status": "unaffected",
"version": "6.5.3",
"versionType": "semver"
},
{
"lessThanOrEqual": "*",
"status": "unaffected",
"version": "6.6",
"versionType": "original_commit_for_fix"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.4.16",
"versionStartIncluding": "5.4",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.5.3",
"versionStartIncluding": "5.4",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.6",
"versionStartIncluding": "5.4",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
]
}
],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nblk-cgroup: Fix NULL deref caused by blkg_policy_data being installed before init\n\nblk-iocost sometimes causes the following crash:\n\n BUG: kernel NULL pointer dereference, address: 00000000000000e0\n ...\n RIP: 0010:_raw_spin_lock+0x17/0x30\n 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 \u003cf0\u003e 0f b1 0f 75 02 5d c3 89 c6 e8 ea 04 00 00 5d c3 0f 1f 84 00 00\n RSP: 0018:ffffc900023b3d40 EFLAGS: 00010046\n RAX: 0000000000000000 RBX: 00000000000000e0 RCX: 0000000000000001\n RDX: ffffc900023b3d20 RSI: ffffc900023b3cf0 RDI: 00000000000000e0\n RBP: ffffc900023b3d40 R08: ffffc900023b3c10 R09: 0000000000000003\n R10: 0000000000000064 R11: 000000000000000a R12: ffff888102337000\n R13: fffffffffffffff2 R14: ffff88810af408c8 R15: ffff8881070c3600\n FS: 00007faaaf364fc0(0000) GS:ffff88842fdc0000(0000) knlGS:0000000000000000\n CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033\n CR2: 00000000000000e0 CR3: 00000001097b1000 CR4: 0000000000350ea0\n Call Trace:\n \u003cTASK\u003e\n ioc_weight_write+0x13d/0x410\n cgroup_file_write+0x7a/0x130\n kernfs_fop_write_iter+0xf5/0x170\n vfs_write+0x298/0x370\n ksys_write+0x5f/0xb0\n __x64_sys_write+0x1b/0x20\n do_syscall_64+0x3d/0x80\n entry_SYSCALL_64_after_hwframe+0x46/0xb0\n\nThis happens because iocg-\u003eioc is NULL. The field is initialized by\nioc_pd_init() and never cleared. The NULL deref is caused by\nblkcg_activate_policy() installing blkg_policy_data before initializing it.\n\nblkcg_activate_policy() was doing the following:\n\n1. Allocate pd\u0027s for all existing blkg\u0027s and install them in blkg-\u003epd[].\n2. Initialize all pd\u0027s.\n3. Online all pd\u0027s.\n\nblkcg_activate_policy() only grabs the queue_lock and may release and\nre-acquire the lock as allocation may need to sleep. ioc_weight_write()\ngrabs blkcg-\u003elock and iterates all its blkg\u0027s. The two can race and if\nioc_weight_write() runs during #1 or between #1 and #2, it can encounter a\npd which is not initialized yet, leading to crash.\n\nThe crash can be reproduced with the following script:\n\n #!/bin/bash\n\n echo +io \u003e /sys/fs/cgroup/cgroup.subtree_control\n systemd-run --unit touch-sda --scope dd if=/dev/sda of=/dev/null bs=1M count=1 iflag=direct\n echo 100 \u003e /sys/fs/cgroup/system.slice/io.weight\n bash -c \"echo \u00278:0 enable=1\u0027 \u003e /sys/fs/cgroup/io.cost.qos\" \u0026\n sleep .2\n echo 100 \u003e /sys/fs/cgroup/system.slice/io.weight\n\nwith the following patch applied:\n\n\u003e diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c\n\u003e index fc49be622e05..38d671d5e10c 100644\n\u003e --- a/block/blk-cgroup.c\n\u003e +++ b/block/blk-cgroup.c\n\u003e @@ -1553,6 +1553,12 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)\n\u003e \t\tpd-\u003eonline = false;\n\u003e \t}\n\u003e\n\u003e + if (system_state == SYSTEM_RUNNING) {\n\u003e + spin_unlock_irq(\u0026q-\u003equeue_lock);\n\u003e + ssleep(1);\n\u003e + spin_lock_irq(\u0026q-\u003equeue_lock);\n\u003e + }\n\u003e +\n\u003e \t/* all allocated, init in the same order */\n\u003e \tif (pol-\u003epd_init_fn)\n\u003e \t\tlist_for_each_entry_reverse(blkg, \u0026q-\u003eblkg_list, q_node)\n\nI don\u0027t see a reason why all pd\u0027s should be allocated, initialized and\nonlined together. The only ordering requirement is that parent blkgs to be\ninitialized and onlined before children, which is guaranteed from the\nwalking order. Let\u0027s fix the bug by allocating, initializing and onlining pd\nfor each blkg and holding blkcg-\u003elock over initialization and onlining. This\nensures that an installed blkg is always fully initialized and onlined\nremoving the the race window."
}
],
"providerMetadata": {
"dateUpdated": "2025-12-30T12:16:01.672Z",
"orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"shortName": "Linux"
},
"references": [
{
"url": "https://git.kernel.org/stable/c/e39ef7880d1057b2ebcdb013405f4d84a257db23"
},
{
"url": "https://git.kernel.org/stable/c/7d63c6f9765339dcfc34b7365ced7c518012e4fe"
},
{
"url": "https://git.kernel.org/stable/c/ec14a87ee1999b19d8b7ed0fa95fea80644624ae"
}
],
"title": "blk-cgroup: Fix NULL deref caused by blkg_policy_data being installed before init",
"x_generator": {
"engine": "bippy-1.2.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"assignerShortName": "Linux",
"cveId": "CVE-2023-54271",
"datePublished": "2025-12-30T12:16:01.672Z",
"dateReserved": "2025-12-30T12:06:44.519Z",
"dateUpdated": "2025-12-30T12:16:01.672Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"vulnerability-lookup:meta": {
"nvd": "{\"cve\":{\"id\":\"CVE-2023-54271\",\"sourceIdentifier\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"published\":\"2025-12-30T13:16:16.000\",\"lastModified\":\"2025-12-30T13:16:16.000\",\"vulnStatus\":\"Received\",\"cveTags\":[],\"descriptions\":[{\"lang\":\"en\",\"value\":\"In the Linux kernel, the following vulnerability has been resolved:\\n\\nblk-cgroup: Fix NULL deref caused by blkg_policy_data being installed before init\\n\\nblk-iocost sometimes causes the following crash:\\n\\n BUG: kernel NULL pointer dereference, address: 00000000000000e0\\n ...\\n RIP: 0010:_raw_spin_lock+0x17/0x30\\n 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 \u003cf0\u003e 0f b1 0f 75 02 5d c3 89 c6 e8 ea 04 00 00 5d c3 0f 1f 84 00 00\\n RSP: 0018:ffffc900023b3d40 EFLAGS: 00010046\\n RAX: 0000000000000000 RBX: 00000000000000e0 RCX: 0000000000000001\\n RDX: ffffc900023b3d20 RSI: ffffc900023b3cf0 RDI: 00000000000000e0\\n RBP: ffffc900023b3d40 R08: ffffc900023b3c10 R09: 0000000000000003\\n R10: 0000000000000064 R11: 000000000000000a R12: ffff888102337000\\n R13: fffffffffffffff2 R14: ffff88810af408c8 R15: ffff8881070c3600\\n FS: 00007faaaf364fc0(0000) GS:ffff88842fdc0000(0000) knlGS:0000000000000000\\n CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033\\n CR2: 00000000000000e0 CR3: 00000001097b1000 CR4: 0000000000350ea0\\n Call Trace:\\n \u003cTASK\u003e\\n ioc_weight_write+0x13d/0x410\\n cgroup_file_write+0x7a/0x130\\n kernfs_fop_write_iter+0xf5/0x170\\n vfs_write+0x298/0x370\\n ksys_write+0x5f/0xb0\\n __x64_sys_write+0x1b/0x20\\n do_syscall_64+0x3d/0x80\\n entry_SYSCALL_64_after_hwframe+0x46/0xb0\\n\\nThis happens because iocg-\u003eioc is NULL. The field is initialized by\\nioc_pd_init() and never cleared. The NULL deref is caused by\\nblkcg_activate_policy() installing blkg_policy_data before initializing it.\\n\\nblkcg_activate_policy() was doing the following:\\n\\n1. Allocate pd\u0027s for all existing blkg\u0027s and install them in blkg-\u003epd[].\\n2. Initialize all pd\u0027s.\\n3. Online all pd\u0027s.\\n\\nblkcg_activate_policy() only grabs the queue_lock and may release and\\nre-acquire the lock as allocation may need to sleep. ioc_weight_write()\\ngrabs blkcg-\u003elock and iterates all its blkg\u0027s. The two can race and if\\nioc_weight_write() runs during #1 or between #1 and #2, it can encounter a\\npd which is not initialized yet, leading to crash.\\n\\nThe crash can be reproduced with the following script:\\n\\n #!/bin/bash\\n\\n echo +io \u003e /sys/fs/cgroup/cgroup.subtree_control\\n systemd-run --unit touch-sda --scope dd if=/dev/sda of=/dev/null bs=1M count=1 iflag=direct\\n echo 100 \u003e /sys/fs/cgroup/system.slice/io.weight\\n bash -c \\\"echo \u00278:0 enable=1\u0027 \u003e /sys/fs/cgroup/io.cost.qos\\\" \u0026\\n sleep .2\\n echo 100 \u003e /sys/fs/cgroup/system.slice/io.weight\\n\\nwith the following patch applied:\\n\\n\u003e diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c\\n\u003e index fc49be622e05..38d671d5e10c 100644\\n\u003e --- a/block/blk-cgroup.c\\n\u003e +++ b/block/blk-cgroup.c\\n\u003e @@ -1553,6 +1553,12 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)\\n\u003e \\t\\tpd-\u003eonline = false;\\n\u003e \\t}\\n\u003e\\n\u003e + if (system_state == SYSTEM_RUNNING) {\\n\u003e + spin_unlock_irq(\u0026q-\u003equeue_lock);\\n\u003e + ssleep(1);\\n\u003e + spin_lock_irq(\u0026q-\u003equeue_lock);\\n\u003e + }\\n\u003e +\\n\u003e \\t/* all allocated, init in the same order */\\n\u003e \\tif (pol-\u003epd_init_fn)\\n\u003e \\t\\tlist_for_each_entry_reverse(blkg, \u0026q-\u003eblkg_list, q_node)\\n\\nI don\u0027t see a reason why all pd\u0027s should be allocated, initialized and\\nonlined together. The only ordering requirement is that parent blkgs to be\\ninitialized and onlined before children, which is guaranteed from the\\nwalking order. Let\u0027s fix the bug by allocating, initializing and onlining pd\\nfor each blkg and holding blkcg-\u003elock over initialization and onlining. This\\nensures that an installed blkg is always fully initialized and onlined\\nremoving the the race window.\"}],\"metrics\":{},\"references\":[{\"url\":\"https://git.kernel.org/stable/c/7d63c6f9765339dcfc34b7365ced7c518012e4fe\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/e39ef7880d1057b2ebcdb013405f4d84a257db23\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/ec14a87ee1999b19d8b7ed0fa95fea80644624ae\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"}]}}"
}
}
Loading…
Loading…
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
Loading…