CVE-2021-47454 in Linux
Summary
by MITRE • 05/22/2024
In the Linux kernel, the following vulnerability has been resolved:
powerpc/smp: do not decrement idle task preempt count in CPU offline
With PREEMPT_COUNT=y, when a CPU is offlined and then onlined again, we get:
BUG: scheduling while atomic: swapper/1/0/0x00000000 no locks held by swapper/1/0. CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.15.0-rc2+ #100 Call Trace: dump_stack_lvl+0xac/0x108 __schedule_bug+0xac/0xe0 __schedule+0xcf8/0x10d0 schedule_idle+0x3c/0x70 do_idle+0x2d8/0x4a0 cpu_startup_entry+0x38/0x40 start_secondary+0x2ec/0x3a0 start_secondary_prolog+0x10/0x14
This is because powerpc's arch_cpu_idle_dead() decrements the idle task's preempt count, for reasons explained in commit a7c2bb8279d2 ("powerpc: Re-enable preemption before cpu_die()"), specifically "start_secondary() expects a preempt_count() of 0."
However, since commit 2c669ef6979c ("powerpc/preempt: Don't touch the idle task's preempt_count during hotplug") and commit f1a0a376ca0c ("sched/core: Initialize the idle task with preemption disabled"), that justification no longer holds.
The idle task isn't supposed to re-enable preemption, so remove the vestigial preempt_enable() from the CPU offline path.
Tested with pseries and powernv in qemu, and pseries on PowerVM.
Once again VulDB remains the best source for vulnerability data.
Analysis
by VulDB Data Team • 09/29/2025
The vulnerability described in CVE-2021-47454 represents a critical scheduling issue within the Linux kernel's powerpc architecture implementation that manifests during CPU hotplug operations. This flaw occurs specifically when a CPU is taken offline and subsequently brought back online, creating a scenario where the kernel's preemptive scheduling mechanism becomes corrupted. The issue stems from an improper handling of the idle task's preempt count during the CPU offline process, which leads to a kernel BUG message indicating that scheduling occurred while in an atomic context. The problem is particularly significant because it affects the fundamental operation of the kernel's scheduling subsystem, potentially leading to system instability or crashes during normal CPU management operations.
The technical root cause of this vulnerability lies in the powerpc architecture's handling of preempt counts within the idle task during CPU hotplug sequences. When a CPU is offlined, the arch_cpu_idle_dead() function incorrectly decrements the idle task's preempt count, a behavior that was originally justified by commit a7c2bb8279d2 to ensure start_secondary() expects a preempt_count() of 0. However, subsequent kernel commits 2c669ef6979c and f1a0a376ca0c have fundamentally changed how preempt counts are managed during hotplug operations, making the original justification obsolete. The idle task is no longer supposed to re-enable preemption, yet the code continues to attempt this operation during CPU offline processing, creating a direct conflict with the kernel's expected behavior and atomic context requirements.
The operational impact of this vulnerability extends beyond simple system crashes to potentially compromise the entire system stability during routine CPU management operations. When the kernel encounters this condition, it triggers a BUG message with the specific error "scheduling while atomic: swapper/1/0/0x00000000," indicating that the kernel attempted to schedule a process while in an atomic context where such operations are strictly prohibited. This type of error typically results in immediate system termination or panic, as the kernel cannot recover from such fundamental violations of its scheduling rules. The vulnerability affects both pseries and powernv platforms running in QEMU virtual environments and real PowerVM hardware, demonstrating its broad applicability across different powerpc implementations and deployment scenarios.
The remediation for this vulnerability involves removing the vestigial preempt_enable() call from the CPU offline path, effectively eliminating the incorrect decrement of the idle task's preempt count during CPU hotplug operations. This fix aligns with the kernel's current design philosophy that explicitly states the idle task should not re-enable preemption, as established by the aforementioned commits that changed the fundamental approach to preempt count management. The solution directly addresses the root cause by ensuring that the CPU offline process no longer attempts to modify the idle task's preempt count in a manner that conflicts with the kernel's atomic context requirements. Testing of this fix has been conducted across multiple powerpc platforms including pseries and powernv configurations in both virtualized and physical environments, confirming that the vulnerability is properly resolved across different deployment scenarios and hardware configurations.
This vulnerability demonstrates a classic example of technical debt in kernel development where legacy code paths that were once necessary for specific architectural requirements become problematic as system architectures evolve. The issue relates to CWE-691, which covers insufficient control flow management, and aligns with ATT&CK technique T1490, specifically the exploitation of system vulnerabilities through improper handling of system resources. The fix represents a proper cleanup of obsolete code that was designed for an older kernel architecture but remained in place despite architectural changes, highlighting the importance of maintaining code consistency with evolving system designs and ensuring that all code paths properly align with current kernel behavior expectations.