[PATCH v5 2/2] iio: adc: ad_sigma_delta: fix clear_pending_event for registerless devices
From: Radu Sabau via B4 Relay
Date: Wed May 27 2026 - 05:39:18 EST
From: Radu Sabau <radu.sabau@xxxxxxxxxx>
ad_sigma_delta_clear_pending_event() falls through to the status register
read path for devices with has_registers = false and no rdy_gpiod. For
such devices, ad_sd_read_reg() skips the address byte entirely and clocks
raw MISO bytes with no address phase — making it byte-for-byte identical
to reading conversion data. If a pending conversion result is present,
this partially consumes it and corrupts the data stream for the subsequent
ad_sd_read_reg() call in ad_sigma_delta_single_conversion().
Furthermore, with num_resetclks = 0 on these devices, data_read_len
evaluates to 0. If the clocked byte has bit 7 clear, pending_event is set
and the code attempts memset(data + 2, 0xff, 0 - 1), overflowing to
SIZE_MAX and corrupting the heap.
Fix by returning 0 immediately when neither rdy_gpiod nor has_registers
is set. This is safe for all current registerless devices: ad7191 and
ad7780 (with powerdown GPIO) are reset between conversions by CS
deassertion, so there is no stale result to drain; ad7780 (without
powerdown GPIO) and max11205 are continuously-converting and cycle ~DRDY
at the output data rate regardless of whether the previous result was
read, so the next falling edge fires naturally.
A future registerless device that holds ~DRDY asserted until data is read
would be broken by this early return and would require either
num_resetclks set or a rdy-gpio.
The same heap corruption is reachable on any device with rdy_gpiod set
but num_resetclks = 0: if the GPIO indicates a pending event, the drain
path executes memset(data + 2, 0xff, 0 - 1) regardless of has_registers.
Add an explicit data_read_len == 0 guard after the pending event check;
the stale result is then consumed by the first ad_sd_read_reg() call in
ad_sigma_delta_single_conversion().
Signed-off-by: Radu Sabau <radu.sabau@xxxxxxxxxx>
---
drivers/iio/adc/ad_sigma_delta.c | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
index 651ade67ad2e..1b410291da53 100644
--- a/drivers/iio/adc/ad_sigma_delta.c
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -262,11 +262,25 @@ static int ad_sigma_delta_clear_pending_event(struct ad_sigma_delta *sigma_delta
/*
* Read R̅D̅Y̅ pin (if possible) or status register to check if there is an
- * old event.
+ * old event. For devices with neither an RDY GPIO nor registers,
+ * ad_sd_read_reg() transmits no address byte and clocks raw MISO bytes,
+ * which is indistinguishable from reading conversion data and would
+ * partially consume a pending result. Skip the check for such devices.
+ *
+ * This is safe for all current registerless devices: ad7191 and ad7780
+ * (with powerdown GPIO) are reset between conversions by CS deassertion,
+ * so there is no stale result to drain; ad7780 (without powerdown GPIO)
+ * and max11205 are continuously-converting and cycle ~DRDY at the output
+ * data rate regardless of whether the previous result was read, so the
+ * next falling edge fires naturally.
+ *
+ * A future registerless device that holds ~DRDY asserted until data is
+ * read would be broken by this early return and would need either
+ * num_resetclks set or a rdy-gpio.
*/
if (sigma_delta->rdy_gpiod) {
pending_event = gpiod_get_value(sigma_delta->rdy_gpiod);
- } else {
+ } else if (sigma_delta->info->has_registers) {
unsigned int status_reg;
ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_STATUS, 1, &status_reg);
@@ -274,11 +288,24 @@ static int ad_sigma_delta_clear_pending_event(struct ad_sigma_delta *sigma_delta
return ret;
pending_event = !(status_reg & AD_SD_REG_STATUS_RDY);
+ } else {
+ return 0;
}
if (!pending_event)
return 0;
+ /*
+ * With num_resetclks = 0, data_read_len is 0 and the drain sequence
+ * below would compute memset(data + 2, 0xff, 0 - 1), underflowing to
+ * SIZE_MAX and corrupting the heap. There is no safe way to drain the
+ * stale result without knowing the data register size; it will be
+ * consumed by the first ad_sd_read_reg() call in
+ * ad_sigma_delta_single_conversion().
+ */
+ if (!data_read_len)
+ return 0;
+
/*
* In general the size of the data register is unknown. It varies from
* device to device, might be one byte longer if CONTROL.DATA_STATUS is
--
2.43.0