VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45968

CVE-2026-45968

Description

In the Linux kernel, the following vulnerability has been resolved:

cpuidle: Skip governor when only one idle state is available

On certain platforms (PowerNV systems without a power-mgt DT node), cpuidle may register only a single idle state. In cases where that single state is a polling state (state 0), the ladder governor may incorrectly treat state 1 as the first usable state and pass an out-of-bounds index. This can lead to a NULL enter callback being invoked, ultimately resulting in a system crash.

[ 13.342636] cpuidle-powernv : Only Snooze is available [ 13.351854] Faulting instruction address: 0x00000000 [ 13.376489] NIP [0000000000000000] 0x0 [ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668

Fix this by adding a bail-out in cpuidle_select() that returns state 0 directly when state_count <= 1, bypassing the governor and keeping the tick running.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A missing bounds check in Linux kernel's cpuidle governor causes a NULL pointer dereference and system crash when only one idle state is available.

Vulnerability

In the Linux kernel, the cpuidle subsystem's cpuidle_select() function lacks a guard against the case where only a single idle state is registered, such as on PowerNV systems without a power management device tree node. The ladder governor incorrectly accesses an out-of-bounds index (state 1) when only one polling state (state 0) is available, leading to a NULL pointer dereference and system crash. This affects kernel versions prior to the fix [1].

Exploitation

An attacker does not directly trigger this vulnerability; it is encountered at boot time on affected hardware configurations. The condition automatically occurs when the cpuidle driver registers only one idle state (e.g., Snooze) and the ladder governor assumes state 1 exists. No authentication or user interaction is required; the crash happens during normal system initialization.

Impact

The bug results in a system crash (denial of service) with a NULL function pointer call, as seen in the kernel log showing NIP [0000000000000000]. The crash prevents the system from completing boot, rendering the machine unavailable. No privilege escalation or data disclosure is involved.

Mitigation

The fix is included in Linux kernel commit 8f6833d919bae915ead6c599a53e81e19b32da52 [1]. This commit adds a bail-out in cpuidle_select() that returns state 0 directly when state_count <= 1, bypassing the governor. Users should apply the patch or update to a kernel version containing this commit. No workaround is available without patching.

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

16
e5c9ffc6ae1b

cpuidle: Skip governor when only one idle state is available

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAboorva DevarajanFeb 16, 2026Fixed in 7.0via kernel-cna
1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index c7876e9e024f90..65fbb8e807b977 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -359,6 +359,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
a0f7e804edc8

cpuidle: Skip governor when only one idle state is available

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAboorva DevarajanFeb 16, 2026Fixed in 5.10.252via kernel-cna
1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index 1c1fa6ac9244ad..87a57cee40fcb2 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -319,6 +319,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
5d103a38e2ae

cpuidle: Skip governor when only one idle state is available

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAboorva DevarajanFeb 16, 2026Fixed in 5.15.202via kernel-cna
1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index e371d6972f8d92..20b9f77a8fb02f 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -319,6 +319,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
4da2b897283c

cpuidle: Skip governor when only one idle state is available

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAboorva DevarajanFeb 16, 2026Fixed in 6.1.165via kernel-cna
1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index fdd25271106a3a..482bf87354a38b 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -324,6 +324,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
5c577ac939bc

cpuidle: Skip governor when only one idle state is available

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAboorva DevarajanFeb 16, 2026Fixed in 6.6.128via kernel-cna
1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index 6704d610573ad6..aa117f2967fdfc 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -356,6 +356,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
8f6833d919ba

cpuidle: Skip governor when only one idle state is available

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAboorva DevarajanFeb 16, 2026Fixed in 6.12.75via kernel-cna
1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index 0e1bbc966135d9..2cb11e5a11251b 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -353,6 +353,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
63ae78336f40

cpuidle: Skip governor when only one idle state is available

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAboorva DevarajanFeb 16, 2026Fixed in 6.18.14via kernel-cna
1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index 56132e843c9919..8950796a493deb 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -357,6 +357,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
a0724e40a58a

cpuidle: Skip governor when only one idle state is available

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAboorva DevarajanFeb 16, 2026Fixed in 6.19.4via kernel-cna
1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index c7876e9e024f90..65fbb8e807b977 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -359,6 +359,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
63ae78336f40

cpuidle: Skip governor when only one idle state is available

1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index 56132e843c9919..8950796a493deb 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -357,6 +357,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
4da2b897283c

cpuidle: Skip governor when only one idle state is available

1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index fdd25271106a3a..482bf87354a38b 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -324,6 +324,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
5c577ac939bc

cpuidle: Skip governor when only one idle state is available

1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index 6704d610573ad6..aa117f2967fdfc 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -356,6 +356,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
5d103a38e2ae

cpuidle: Skip governor when only one idle state is available

1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index e371d6972f8d92..20b9f77a8fb02f 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -319,6 +319,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
8f6833d919ba

cpuidle: Skip governor when only one idle state is available

1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index 0e1bbc966135d9..2cb11e5a11251b 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -353,6 +353,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
a0724e40a58a

cpuidle: Skip governor when only one idle state is available

1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index c7876e9e024f90..65fbb8e807b977 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -359,6 +359,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
a0f7e804edc8

cpuidle: Skip governor when only one idle state is available

1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index 1c1fa6ac9244ad..87a57cee40fcb2 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -319,6 +319,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
e5c9ffc6ae1b

cpuidle: Skip governor when only one idle state is available

1 file changed · +10 1
  • drivers/cpuidle/cpuidle.c+10 1 modified
    diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
    index c7876e9e024f90..65fbb8e807b977 100644
    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -359,6 +359,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
     int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
     		   bool *stop_tick)
     {
    +	/*
    +	 * If there is only a single idle state (or none), there is nothing
    +	 * meaningful for the governor to choose. Skip the governor and
    +	 * always use state 0 with the tick running.
    +	 */
    +	if (drv->state_count <= 1) {
    +		*stop_tick = false;
    +		return 0;
    +	}
    +
     	return cpuidle_curr_governor->select(drv, dev, stop_tick);
     }
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing bounds guard in cpuidle_select() allows the ladder governor to compute an out-of-bounds state index when only one idle state is registered."

Attack vector

On PowerNV systems without a power-mgt device-tree node, cpuidle registers only a single polling state (state 0, "Snooze"). The ladder governor incorrectly treats state 1 as the first usable state and passes an out-of-bounds index to `cpuidle_enter_state()`. This results in a NULL `enter` callback being invoked, causing a kernel crash (NULL pointer dereference at instruction address 0x0) [patch_id=2660885]. No special privileges or network access are required — the crash occurs during normal idle entry on affected hardware configurations.

Affected code

The vulnerability resides in `drivers/cpuidle/cpuidle.c` in the `cpuidle_select()` function [patch_id=2660885]. When `drv->state_count` is 1 (only a single idle state available), the function unconditionally calls `cpuidle_curr_governor->select(drv, dev, stop_tick)`, which can cause the ladder governor to compute an out-of-bounds state index.

What the fix does

The patch adds an early return at the top of `cpuidle_select()`: if `drv->state_count <= 1`, the function sets `*stop_tick = false` and returns 0 directly, bypassing the governor entirely [patch_id=2660885]. This prevents the ladder governor from ever computing an out-of-bounds index when only a single polling state exists. The tick is kept running because there is no deeper idle state to enter.

Preconditions

  • configPowerNV system without a power-mgt device-tree node, causing cpuidle to register only a single idle state (the polling 'Snooze' state)
  • configThe ladder governor must be the active cpuidle governor

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.