CVE-2026-45914
Description
In the Linux kernel, the following vulnerability has been resolved:
Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
This reverts commit 6946c726c3f4c36f0f049e6f97e88c510b15f65d.
Jean Delvare points out that the patch does not completely fix the reported problem, that it in fact introduces a (new) race condition, and that it may actually not be needed in the first place.
Various AI reviews agree. Specific and relevant AI feedback:
" This reordering sets the driver data to NULL before removing the sensor attributes in the loop below.
ibmpex_show_sensor() retrieves this driver data via dev_get_drvdata() but does not check if it is NULL before dereferencing it to access data->sensors[].
If a userspace process reads a sensor file (like temp1_input) while this delete function is running, could it race with the dev_set_drvdata(..., NULL) call here and crash in ibmpex_show_sensor()?
Would it be safer to keep the original order where device_remove_file() is called before clearing the driver data? device_remove_file() should wait for any active sysfs callbacks to complete, which might already prevent the use-after-free this patch intends to fix. "
Revert the offending patch. If it can be shown that the originally reported alleged race condition does indeed exist, it can always be re-introduced with a complete fix.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A previous fix for a use-after-free in the Linux kernel's ibmpex hwmon driver was reverted because it introduced a new race condition, leaving the original issue unresolved.
Vulnerability
The Linux kernel's ibmpex hwmon driver contained a potential use-after-free in ibmpex_show_sensor() when sensor attributes are removed. A previous commit (6946c726c3f4) attempted to fix this by reordering operations, but it introduced a new race condition where dev_set_drvdata(..., NULL) could be called before device_remove_file() completes, allowing a concurrent sysfs read to dereference a NULL pointer. This commit was reverted in commit f448acd86835 [1]. The affected versions include any kernel that contained the faulty fix.
Exploitation
An attacker with local access and the ability to trigger a sysfs read (e.g., reading temp1_input) while sensor attributes are being removed could race with the NULL assignment in the faulty fix, leading to a NULL pointer dereference. The original use-after-free scenario, if it exists, would also require a race between attribute removal and a concurrent read.
Impact
Successful exploitation could cause a kernel crash (denial of service) or potentially lead to information disclosure if the use-after-free is triggered. The impact is limited to local users with the ability to interact with the hwmon sysfs interface.
Mitigation
The revert commit f448acd86835 [1] restores the original code, removing the introduced race condition. Users should update to a kernel version that includes this revert. No workaround is available; the original potential issue remains unaddressed.
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
1Patches
15efd68429f23fRevert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 9c7e2fa395dbfa..1837cccd993c8f 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -282,9 +282,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -517,9 +514,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); @@ -533,7 +527,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
05112ba67c82Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 235d56e96879ce..fe90f0536d76c1 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -282,9 +282,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -517,9 +514,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); @@ -533,7 +527,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
8bde3e395a85Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 129f3a9e8fe965..228c5f6c6f3836 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -277,9 +277,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -511,9 +508,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &dev_attr_name.attr); @@ -527,7 +521,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
894d9c7aab68Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 129f3a9e8fe965..228c5f6c6f3836 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -277,9 +277,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -511,9 +508,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &dev_attr_name.attr); @@ -527,7 +521,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
14a38784e09aRevert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 129f3a9e8fe965..228c5f6c6f3836 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -277,9 +277,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -511,9 +508,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &dev_attr_name.attr); @@ -527,7 +521,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
914b47c9b824Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 129f3a9e8fe965..228c5f6c6f3836 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -277,9 +277,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -511,9 +508,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &dev_attr_name.attr); @@ -527,7 +521,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
f448acd86835Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 40fff7e95ea1c0..db066b3689187d 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -282,9 +282,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -517,9 +514,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); @@ -533,7 +527,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
6946c726c3f4hwmon: (ibmpex) fix use-after-free in high/low store
1 file changed · +7 −2
drivers/hwmon/ibmpex.c+7 −2 modified@@ -277,6 +277,9 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); + if (!data) + return -ENODEV; + ibmpex_reset_high_low_data(data); return count; @@ -508,6 +511,9 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; + hwmon_device_unregister(data->hwmon_dev); + dev_set_drvdata(data->bmc_device, NULL); + device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &dev_attr_name.attr); @@ -521,8 +527,7 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - dev_set_drvdata(data->bmc_device, NULL); - hwmon_device_unregister(data->hwmon_dev); + ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data);
f448acd86835Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 40fff7e95ea1c0..db066b3689187d 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -282,9 +282,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -517,9 +514,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); @@ -533,7 +527,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
efd68429f23fRevert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 9c7e2fa395dbfa..1837cccd993c8f 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -282,9 +282,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -517,9 +514,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); @@ -533,7 +527,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
914b47c9b824Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 129f3a9e8fe965..228c5f6c6f3836 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -277,9 +277,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -511,9 +508,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &dev_attr_name.attr); @@ -527,7 +521,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
8bde3e395a85Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 129f3a9e8fe965..228c5f6c6f3836 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -277,9 +277,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -511,9 +508,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &dev_attr_name.attr); @@ -527,7 +521,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
894d9c7aab68Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 129f3a9e8fe965..228c5f6c6f3836 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -277,9 +277,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -511,9 +508,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &dev_attr_name.attr); @@ -527,7 +521,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
14a38784e09aRevert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 129f3a9e8fe965..228c5f6c6f3836 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -277,9 +277,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -511,9 +508,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &dev_attr_name.attr); @@ -527,7 +521,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
05112ba67c82Revert "hwmon: (ibmpex) fix use-after-free in high/low store"
1 file changed · +2 −8
drivers/hwmon/ibmpex.c+2 −8 modifieddiff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 235d56e96879ce..fe90f0536d76c1 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -282,9 +282,6 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); - if (!data) - return -ENODEV; - ibmpex_reset_high_low_data(data); return count; @@ -517,9 +514,6 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; - hwmon_device_unregister(data->hwmon_dev); - dev_set_drvdata(data->bmc_device, NULL); - device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); @@ -533,7 +527,8 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - + dev_set_drvdata(data->bmc_device, NULL); + hwmon_device_unregister(data->hwmon_dev); ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Reordering of teardown operations in ibmpex_bmc_delete() sets driver data to NULL before removing sysfs attributes, creating a NULL-pointer dereference race with concurrent sysfs read callbacks."
Attack vector
An attacker with local access to the sysfs interface of the ibmpex hwmon driver can trigger a NULL-pointer dereference race condition. If a userspace process reads a sensor file (e.g. `temp1_input`) via `ibmpex_show_sensor()` while the `ibmpex_bmc_delete()` function is concurrently running, the reordered `dev_set_drvdata(..., NULL)` call (introduced by the original patch) sets the driver data to NULL before the sensor attributes are removed. `ibmpex_show_sensor()` retrieves this NULL pointer via `dev_get_drvdata()` and does not check for NULL before dereferencing it to access `data->sensors[]`, causing a crash [patch_id=2664077]. The revert eliminates this new race by restoring the original teardown order where `device_remove_file()` (which waits for active sysfs callbacks to complete) is called before clearing the driver data [patch_id=2661413].
Affected code
The vulnerability is in `drivers/hwmon/ibmpex.c` in the `ibmpex_bmc_delete()` function and the `ibmpex_high_low_store()` / `ibmpex_show_sensor()` sysfs callbacks. The original patch (commit 6946c726c3f4) reordered operations in `ibmpex_bmc_delete()` so that `dev_set_drvdata(data->bmc_device, NULL)` was called *before* `device_remove_file()` for the sensor attributes, and added a NULL check in `ibmpex_high_low_store()`. The revert restores the original order where `device_remove_file()` is called first, then `dev_set_drvdata()` and `hwmon_device_unregister()` are called after the attribute loop.
What the fix does
The revert (commit 8bde3e395a85, [patch_id=2661413]) restores the original teardown order in `ibmpex_bmc_delete()`: `device_remove_file()` is called for all sensor attributes *before* `dev_set_drvdata(data->bmc_device, NULL)` and `hwmon_device_unregister()`. This is safer because `device_remove_file()` waits for any active sysfs callbacks to complete, preventing a concurrent `ibmpex_show_sensor()` from racing with the NULL assignment. The revert also removes the NULL check in `ibmpex_high_low_store()` that was added by the original patch, since with the corrected order the check is unnecessary — the driver data will not be NULL while sysfs files still exist. The commit message notes that if the originally reported race condition can be shown to actually exist, a complete fix can be re-introduced later.
Preconditions
- configThe ibmpex hwmon driver must be loaded and have sensor sysfs files exposed.
- inputAn attacker must have local access to read sensor sysfs files (e.g. temp1_input) while the driver is being removed.
- inputThe race window requires concurrent execution of ibmpex_bmc_delete() and a sysfs read callback.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- git.kernel.org/stable/c/05112ba67c824ab416cd54307c0b50aba9f0047anvd
- git.kernel.org/stable/c/14a38784e09aebc21207dc32fffa05247fc3dd64nvd
- git.kernel.org/stable/c/894d9c7aab68fd0c70c78b1d03c8fa589fb0f67dnvd
- git.kernel.org/stable/c/8bde3e395a85017f12af2b0ba5c3684f5af9c006nvd
- git.kernel.org/stable/c/914b47c9b824d3d74f31c764163edf93302100b1nvd
- git.kernel.org/stable/c/efd68429f23fb4015b0ebc2392334059e06fad18nvd
- git.kernel.org/stable/c/f448acd86835a650f9ea83460b9ca347d3aafba5nvd
News mentions
0No linked articles in our index yet.