VYPR
Unrated severityNVD Advisory· Published Jun 8, 2026

CVE-2026-46292

CVE-2026-46292

Description

Linux kernel PM domain vulnerability allows runtime PM to remain enabled after device detach, potentially causing crashes or performance issues.

AI Insight

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

Linux kernel PM domain vulnerability allows runtime PM to remain enabled after device detach, potentially causing crashes or performance issues.

Vulnerability

The Linux kernel's generic power management domain (genpd) has a vulnerability where virtual devices attached via genpd_dev_pm_attach_by_id() have pm_runtime_enable() called but lack a corresponding pm_runtime_disable() call in genpd_dev_pm_detach(). This results in virtual devices being detached from genpd while runtime power management remains enabled, contrary to design, affecting all versions where this logic exists.

Exploitation

An attacker would need to trigger the detachment of a virtual device from its PM domain while runtime power management is still enabled. The exact conditions for triggering this detachment are not detailed in the available references, but the vulnerability lies in the kernel's internal handling of device power management states.

Impact

Successful exploitation can lead to critical errors, including a NULL pointer dereference in genpd_runtime_suspend(), potentially causing system instability or crashes. In other scenarios, it may result in an unnecessary persistent vote for a device's performance state, negatively impacting power efficiency.

Mitigation

This vulnerability has been resolved by adding the missing pm_runtime_disable() call in genpd_dev_pm_detach(). The fix is available in the Linux kernel via the commit 51a7dd9cbae9210335ce398642ecaaa52c939eb5 [1]. Specific patched kernel versions are not detailed in the available references.

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

Affected products

1

Patches

10
707cb5df3eab

pmdomain: core: Fix detach procedure for virtual devices in genpd

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitUlf HanssonMay 15, 2026Fixed in 6.6.141via kernel-cna
1 file changed · +9 2
  • drivers/base/power/domain.c+9 2 modified
    diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
    index d1dae47f3534b..5bee0a8975003 100644
    --- a/drivers/base/power/domain.c
    +++ b/drivers/base/power/domain.c
    @@ -2676,6 +2676,7 @@ static struct bus_type genpd_bus_type = {
     static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     {
     	struct generic_pm_domain *pd;
    +	bool is_virt_dev;
     	unsigned int i;
     	int ret = 0;
     
    @@ -2685,6 +2686,13 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     
     	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
     
    +	/* Check if the device was created by genpd at attach. */
    +	is_virt_dev = dev->bus == &genpd_bus_type;
    +
    +	/* Disable runtime PM if we enabled it at attach. */
    +	if (is_virt_dev)
    +		pm_runtime_disable(dev);
    +
     	/* Drop the default performance state */
     	if (dev_gpd_data(dev)->default_pstate) {
     		dev_pm_genpd_set_performance_state(dev, 0);
    @@ -2710,7 +2718,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     	genpd_queue_power_off_work(pd);
     
     	/* Unregister the device if it was created by genpd. */
    -	if (dev->bus == &genpd_bus_type)
    +	if (is_virt_dev)
     		device_unregister(dev);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
51a7dd9cbae9

pmdomain: core: Fix detach procedure for virtual devices in genpd

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitUlf HanssonApr 17, 2026Fixed in 6.18.30via kernel-cna
1 file changed · +9 2
  • drivers/pmdomain/core.c+9 2 modified
    diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
    index 61c2277c9ce39..5fd08a5118cb8 100644
    --- a/drivers/pmdomain/core.c
    +++ b/drivers/pmdomain/core.c
    @@ -3074,6 +3074,7 @@ static const struct bus_type genpd_bus_type = {
     static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     {
     	struct generic_pm_domain *pd;
    +	bool is_virt_dev;
     	unsigned int i;
     	int ret = 0;
     
    @@ -3083,6 +3084,13 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     
     	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
     
    +	/* Check if the device was created by genpd at attach. */
    +	is_virt_dev = dev->bus == &genpd_bus_type;
    +
    +	/* Disable runtime PM if we enabled it at attach. */
    +	if (is_virt_dev)
    +		pm_runtime_disable(dev);
    +
     	/* Drop the default performance state */
     	if (dev_gpd_data(dev)->default_pstate) {
     		dev_pm_genpd_set_performance_state(dev, 0);
    @@ -3108,7 +3116,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     	genpd_queue_power_off_work(pd);
     
     	/* Unregister the device if it was created by genpd. */
    -	if (dev->bus == &genpd_bus_type)
    +	if (is_virt_dev)
     		device_unregister(dev);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
8d44391a7f29

pmdomain: core: Fix detach procedure for virtual devices in genpd

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitUlf HanssonApr 17, 2026Fixed in 7.0.7via kernel-cna
1 file changed · +9 2
  • drivers/pmdomain/core.c+9 2 modified
    diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
    index 52ea84e548ff6..f9757dcb255e6 100644
    --- a/drivers/pmdomain/core.c
    +++ b/drivers/pmdomain/core.c
    @@ -3082,6 +3082,7 @@ static const struct bus_type genpd_bus_type = {
     static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     {
     	struct generic_pm_domain *pd;
    +	bool is_virt_dev;
     	unsigned int i;
     	int ret = 0;
     
    @@ -3091,6 +3092,13 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     
     	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
     
    +	/* Check if the device was created by genpd at attach. */
    +	is_virt_dev = dev->bus == &genpd_bus_type;
    +
    +	/* Disable runtime PM if we enabled it at attach. */
    +	if (is_virt_dev)
    +		pm_runtime_disable(dev);
    +
     	/* Drop the default performance state */
     	if (dev_gpd_data(dev)->default_pstate) {
     		dev_pm_genpd_set_performance_state(dev, 0);
    @@ -3116,7 +3124,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     	genpd_queue_power_off_work(pd);
     
     	/* Unregister the device if it was created by genpd. */
    -	if (dev->bus == &genpd_bus_type)
    +	if (is_virt_dev)
     		device_unregister(dev);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
26735dfdd893

pmdomain: core: Fix detach procedure for virtual devices in genpd

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitUlf HanssonApr 17, 2026Fixed in 7.1-rc3via kernel-cna
1 file changed · +9 2
  • drivers/pmdomain/core.c+9 2 modified
    diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
    index 4d32fc676aaf5..71e930e80178e 100644
    --- a/drivers/pmdomain/core.c
    +++ b/drivers/pmdomain/core.c
    @@ -3089,6 +3089,7 @@ static const struct bus_type genpd_bus_type = {
     static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     {
     	struct generic_pm_domain *pd;
    +	bool is_virt_dev;
     	unsigned int i;
     	int ret = 0;
     
    @@ -3098,6 +3099,13 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     
     	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
     
    +	/* Check if the device was created by genpd at attach. */
    +	is_virt_dev = dev->bus == &genpd_bus_type;
    +
    +	/* Disable runtime PM if we enabled it at attach. */
    +	if (is_virt_dev)
    +		pm_runtime_disable(dev);
    +
     	/* Drop the default performance state */
     	if (dev_gpd_data(dev)->default_pstate) {
     		dev_pm_genpd_set_performance_state(dev, 0);
    @@ -3123,7 +3131,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     	genpd_queue_power_off_work(pd);
     
     	/* Unregister the device if it was created by genpd. */
    -	if (dev->bus == &genpd_bus_type)
    +	if (is_virt_dev)
     		device_unregister(dev);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
361518a26e44

pmdomain: core: Fix detach procedure for virtual devices in genpd

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitUlf HanssonApr 17, 2026Fixed in 6.12.88via kernel-cna
1 file changed · +9 2
  • drivers/pmdomain/core.c+9 2 modified
    diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
    index 2643525a572bb..e4a1c63554128 100644
    --- a/drivers/pmdomain/core.c
    +++ b/drivers/pmdomain/core.c
    @@ -2900,6 +2900,7 @@ static const struct bus_type genpd_bus_type = {
     static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     {
     	struct generic_pm_domain *pd;
    +	bool is_virt_dev;
     	unsigned int i;
     	int ret = 0;
     
    @@ -2909,6 +2910,13 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     
     	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
     
    +	/* Check if the device was created by genpd at attach. */
    +	is_virt_dev = dev->bus == &genpd_bus_type;
    +
    +	/* Disable runtime PM if we enabled it at attach. */
    +	if (is_virt_dev)
    +		pm_runtime_disable(dev);
    +
     	/* Drop the default performance state */
     	if (dev_gpd_data(dev)->default_pstate) {
     		dev_pm_genpd_set_performance_state(dev, 0);
    @@ -2934,7 +2942,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     	genpd_queue_power_off_work(pd);
     
     	/* Unregister the device if it was created by genpd. */
    -	if (dev->bus == &genpd_bus_type)
    +	if (is_virt_dev)
     		device_unregister(dev);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
707cb5df3eab

pmdomain: core: Fix detach procedure for virtual devices in genpd

1 file changed · +9 2
  • drivers/base/power/domain.c+9 2 modified
    diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
    index d1dae47f3534b..5bee0a8975003 100644
    --- a/drivers/base/power/domain.c
    +++ b/drivers/base/power/domain.c
    @@ -2676,6 +2676,7 @@ static struct bus_type genpd_bus_type = {
     static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     {
     	struct generic_pm_domain *pd;
    +	bool is_virt_dev;
     	unsigned int i;
     	int ret = 0;
     
    @@ -2685,6 +2686,13 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     
     	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
     
    +	/* Check if the device was created by genpd at attach. */
    +	is_virt_dev = dev->bus == &genpd_bus_type;
    +
    +	/* Disable runtime PM if we enabled it at attach. */
    +	if (is_virt_dev)
    +		pm_runtime_disable(dev);
    +
     	/* Drop the default performance state */
     	if (dev_gpd_data(dev)->default_pstate) {
     		dev_pm_genpd_set_performance_state(dev, 0);
    @@ -2710,7 +2718,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     	genpd_queue_power_off_work(pd);
     
     	/* Unregister the device if it was created by genpd. */
    -	if (dev->bus == &genpd_bus_type)
    +	if (is_virt_dev)
     		device_unregister(dev);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
361518a26e44

pmdomain: core: Fix detach procedure for virtual devices in genpd

1 file changed · +9 2
  • drivers/pmdomain/core.c+9 2 modified
    diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
    index 2643525a572bb..e4a1c63554128 100644
    --- a/drivers/pmdomain/core.c
    +++ b/drivers/pmdomain/core.c
    @@ -2900,6 +2900,7 @@ static const struct bus_type genpd_bus_type = {
     static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     {
     	struct generic_pm_domain *pd;
    +	bool is_virt_dev;
     	unsigned int i;
     	int ret = 0;
     
    @@ -2909,6 +2910,13 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     
     	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
     
    +	/* Check if the device was created by genpd at attach. */
    +	is_virt_dev = dev->bus == &genpd_bus_type;
    +
    +	/* Disable runtime PM if we enabled it at attach. */
    +	if (is_virt_dev)
    +		pm_runtime_disable(dev);
    +
     	/* Drop the default performance state */
     	if (dev_gpd_data(dev)->default_pstate) {
     		dev_pm_genpd_set_performance_state(dev, 0);
    @@ -2934,7 +2942,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     	genpd_queue_power_off_work(pd);
     
     	/* Unregister the device if it was created by genpd. */
    -	if (dev->bus == &genpd_bus_type)
    +	if (is_virt_dev)
     		device_unregister(dev);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
51a7dd9cbae9

pmdomain: core: Fix detach procedure for virtual devices in genpd

1 file changed · +9 2
  • drivers/pmdomain/core.c+9 2 modified
    diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
    index 61c2277c9ce39..5fd08a5118cb8 100644
    --- a/drivers/pmdomain/core.c
    +++ b/drivers/pmdomain/core.c
    @@ -3074,6 +3074,7 @@ static const struct bus_type genpd_bus_type = {
     static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     {
     	struct generic_pm_domain *pd;
    +	bool is_virt_dev;
     	unsigned int i;
     	int ret = 0;
     
    @@ -3083,6 +3084,13 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     
     	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
     
    +	/* Check if the device was created by genpd at attach. */
    +	is_virt_dev = dev->bus == &genpd_bus_type;
    +
    +	/* Disable runtime PM if we enabled it at attach. */
    +	if (is_virt_dev)
    +		pm_runtime_disable(dev);
    +
     	/* Drop the default performance state */
     	if (dev_gpd_data(dev)->default_pstate) {
     		dev_pm_genpd_set_performance_state(dev, 0);
    @@ -3108,7 +3116,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     	genpd_queue_power_off_work(pd);
     
     	/* Unregister the device if it was created by genpd. */
    -	if (dev->bus == &genpd_bus_type)
    +	if (is_virt_dev)
     		device_unregister(dev);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
8d44391a7f29

pmdomain: core: Fix detach procedure for virtual devices in genpd

1 file changed · +9 2
  • drivers/pmdomain/core.c+9 2 modified
    diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
    index 52ea84e548ff6..f9757dcb255e6 100644
    --- a/drivers/pmdomain/core.c
    +++ b/drivers/pmdomain/core.c
    @@ -3082,6 +3082,7 @@ static const struct bus_type genpd_bus_type = {
     static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     {
     	struct generic_pm_domain *pd;
    +	bool is_virt_dev;
     	unsigned int i;
     	int ret = 0;
     
    @@ -3091,6 +3092,13 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     
     	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
     
    +	/* Check if the device was created by genpd at attach. */
    +	is_virt_dev = dev->bus == &genpd_bus_type;
    +
    +	/* Disable runtime PM if we enabled it at attach. */
    +	if (is_virt_dev)
    +		pm_runtime_disable(dev);
    +
     	/* Drop the default performance state */
     	if (dev_gpd_data(dev)->default_pstate) {
     		dev_pm_genpd_set_performance_state(dev, 0);
    @@ -3116,7 +3124,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     	genpd_queue_power_off_work(pd);
     
     	/* Unregister the device if it was created by genpd. */
    -	if (dev->bus == &genpd_bus_type)
    +	if (is_virt_dev)
     		device_unregister(dev);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
26735dfdd893

pmdomain: core: Fix detach procedure for virtual devices in genpd

1 file changed · +9 2
  • drivers/pmdomain/core.c+9 2 modified
    diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
    index 4d32fc676aaf5..71e930e80178e 100644
    --- a/drivers/pmdomain/core.c
    +++ b/drivers/pmdomain/core.c
    @@ -3089,6 +3089,7 @@ static const struct bus_type genpd_bus_type = {
     static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     {
     	struct generic_pm_domain *pd;
    +	bool is_virt_dev;
     	unsigned int i;
     	int ret = 0;
     
    @@ -3098,6 +3099,13 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     
     	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
     
    +	/* Check if the device was created by genpd at attach. */
    +	is_virt_dev = dev->bus == &genpd_bus_type;
    +
    +	/* Disable runtime PM if we enabled it at attach. */
    +	if (is_virt_dev)
    +		pm_runtime_disable(dev);
    +
     	/* Drop the default performance state */
     	if (dev_gpd_data(dev)->default_pstate) {
     		dev_pm_genpd_set_performance_state(dev, 0);
    @@ -3123,7 +3131,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
     	genpd_queue_power_off_work(pd);
     
     	/* Unregister the device if it was created by genpd. */
    -	if (dev->bus == &genpd_bus_type)
    +	if (is_virt_dev)
     		device_unregister(dev);
     }
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Synthesis attempt was rejected by the grounding validator. Re-run pending.

References

5

News mentions

1