patch "iio: adc: ad_sigma_delta: fix clear_pending_event for registerless" added to char-misc-testing
Subsystems (3)
This is a note to let you know that I've just added the patch titled
iio: adc: ad_sigma_delta: fix clear_pending_event for registerless
to my char-misc git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
in the char-misc-testing branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will be merged to the char-misc-next branch sometime soon, after it passes testing, and the merge window is open.
If you have any questions about this process, please let me know.
From 91bc6767a4f55dc470d8a56b55b9f2ea09094efe Mon Sep 17 00:00:00 2001
From: Radu Sabau <[email protected]>
Date: Wed, 27 May 2026 12:38:39 +0300
Subject: iio: adc: ad_sigma_delta: fix clear_pending_event for registerless
devices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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().
--- drivers/iio/adc/ad_sigma_delta.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)
drivers/iio/adc/ad_sigma_delta.c +29 -2
@@ -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_deltareturn 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
Signature · 1 line
2.54.0