CVE-2026-46007
Description
In the Linux kernel, the following vulnerability has been resolved:
hwmon: (powerz) Avoid cacheline sharing for DMA buffer
Depending on the architecture the transfer buffer may share a cacheline with the following mutex. As the buffer may be used for DMA, that is problematic.
Use the high-level DMA helpers to make sure that cacheline sharing can not happen.
Also drop the comment, as the helpers are documentation enough.
https://sashiko.dev/#/message/20260408175814.934BFC19421%40smtp.kernel.org
Affected products
1Patches
81869da3efe70hwmon: (powerz) Avoid cacheline sharing for DMA buffer
2 files changed · +8 −4
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
2fa2273016a0hwmon: (powerz) Avoid cacheline sharing for DMA buffer
2 files changed · +8 −4
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
3023c050af36hwmon: (powerz) Avoid cacheline sharing for DMA buffer
2 files changed · +8 −4
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
270e5c576a6ehwmon: (powerz) Avoid cacheline sharing for DMA buffer
2 files changed · +8 −4
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index da6dd48ac67c5a..c92dd3358d2e4e 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index da6dd48ac67c5a..c92dd3358d2e4e 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
1869da3efe70hwmon: (powerz) Avoid cacheline sharing for DMA buffer
2 files changed · +8 −4
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
3023c050af36hwmon: (powerz) Avoid cacheline sharing for DMA buffer
2 files changed · +8 −4
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
270e5c576a6ehwmon: (powerz) Avoid cacheline sharing for DMA buffer
2 files changed · +8 −4
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index da6dd48ac67c5a..c92dd3358d2e4e 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index da6dd48ac67c5a..c92dd3358d2e4e 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
2fa2273016a0hwmon: (powerz) Avoid cacheline sharing for DMA buffer
2 files changed · +8 −4
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
drivers/hwmon/powerz.c+4 −2 modifieddiff --git a/drivers/hwmon/powerz.c b/drivers/hwmon/powerz.c index 96438f5f05d489..6e1359144cabef 100644 --- a/drivers/hwmon/powerz.c +++ b/drivers/hwmon/powerz.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/hwmon.h> #include <linux/module.h> #include <linux/mutex.h> @@ -33,7 +34,9 @@ struct powerz_sensor_data { } __packed; struct powerz_priv { - char transfer_buffer[64]; /* first member to satisfy DMA alignment */ + __dma_from_device_group_begin(); + char transfer_buffer[64]; + __dma_from_device_group_end(); struct mutex mutex; struct completion completion; struct urb *urb; -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing cacheline alignment for a DMA buffer that could share a cacheline with a mutex, leading to potential DMA-induced memory corruption."
Attack vector
An attacker who can trigger DMA operations on the `transfer_buffer` (which is used for USB transfers via an `urb`) may cause the DMA to corrupt the adjacent `mutex` field if the buffer and mutex share a cacheline. This can lead to memory corruption and potential denial of service or privilege escalation. The attack requires the ability to interact with the POWER-Z USB device to initiate DMA transfers that write to the buffer.
Affected code
The vulnerability is in `drivers/hwmon/powerz.c` within the `struct powerz_priv` definition. The `transfer_buffer[64]` array was placed as the first member with only a comment about DMA alignment, but it could share a cacheline with the following `mutex` field depending on architecture [patch_id=2660489].
What the fix does
The patch replaces the bare `char transfer_buffer[64]` declaration with the `__dma_from_device_group_begin()` and `__dma_from_device_group_end()` DMA helpers, which ensure the buffer is placed on its own cacheline and cannot alias with adjacent fields like `mutex`. It also adds the `#include
Preconditions
- inputAttacker must have access to a POWER-Z USB device connected to the system
- configThe system architecture must have a cacheline size that causes the transfer buffer and mutex to share a cacheline
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.