mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] iio: adc: xilinx-ams: fix OOB read in ams_get_ext_chan()
@ 2026-09-06 11:05 Manush Prajwal
  2026-09-06 17:56 ` Jonathan Cameron
  0 siblings, 1 reply; 2+ messages in thread
From: Manush Prajwal @ 2026-09-06 11:05 UTC (permalink / raw)
  To: sai.krishna.potthuri, conall.ogriofa, jic23
  Cc: linux-iio, linux-kernel, dlechner, nuno.sa, andy

The PL external-channel "reg" property is only checked against its
upper bound (AMS_PL_MAX_EXT_CHANNEL + 30 == 50), matching the
'maximum: 50' constraint in the devicetree binding
(Documentation/devicetree/bindings/iio/adc/xlnx,zynqmp-ams.yaml), but
the binding also documents 'minimum: 20' which the driver never
enforces at runtime.

ext_chan is computed as 'reg + AMS_PL_MAX_FIXED_CHANNEL - 30' in
unsigned arithmetic. For any reg < 20 (e.g. a hand-written or
malformed devicetree overlay with reg = <0>), this underflows to a
huge unsigned value, and the following

	memcpy(chan, &ams_pl_channels[ext_chan], sizeof(*channels));

reads far outside the 31-entry ams_pl_channels[] array.

Reject any reg value that would produce an out-of-range ext_chan
before it is used to index ams_pl_channels[], instead of relying only
on the upper-bound check.

Signed-off-by: Manush Prajwal <manushprajwal555@gmail.com>
---
 drivers/iio/adc/xilinx-ams.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index 158e6133a..cd778d053 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -1154,8 +1154,11 @@ static int ams_get_ext_chan(struct fwnode_handle *chan_node,
 		if (ret || reg > AMS_PL_MAX_EXT_CHANNEL + 30)
 			continue;
 
-		chan = &channels[num_channels];
 		ext_chan = reg + AMS_PL_MAX_FIXED_CHANNEL - 30;
+		if (ext_chan >= ARRAY_SIZE(ams_pl_channels))
+			continue;
+
+		chan = &channels[num_channels];
 		memcpy(chan, &ams_pl_channels[ext_chan], sizeof(*channels));
 
 		if (fwnode_property_read_bool(child, "xlnx,bipolar"))
-- 
2.46.2.windows.1



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] iio: adc: xilinx-ams: fix OOB read in ams_get_ext_chan()
  2026-09-06 11:05 [PATCH] iio: adc: xilinx-ams: fix OOB read in ams_get_ext_chan() Manush Prajwal
@ 2026-09-06 17:56 ` Jonathan Cameron
  0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Cameron @ 2026-09-06 17:56 UTC (permalink / raw)
  To: Manush Prajwal
  Cc: sai.krishna.potthuri, conall.ogriofa, linux-iio, linux-kernel,
	dlechner, nuno.sa, andy

On 6 Sep 2026 16:35:18 +0530
"Manush Prajwal" <manushprajwal555@gmail.com> wrote:

> The PL external-channel "reg" property is only checked against its
> upper bound (AMS_PL_MAX_EXT_CHANNEL + 30 == 50), matching the
> 'maximum: 50' constraint in the devicetree binding
> (Documentation/devicetree/bindings/iio/adc/xlnx,zynqmp-ams.yaml), but
> the binding also documents 'minimum: 20' which the driver never
> enforces at runtime.
> 
> ext_chan is computed as 'reg + AMS_PL_MAX_FIXED_CHANNEL - 30' in
> unsigned arithmetic. For any reg < 20 (e.g. a hand-written or
> malformed devicetree overlay with reg = <0>), this underflows to a
> huge unsigned value, and the following
> 
> 	memcpy(chan, &ams_pl_channels[ext_chan], sizeof(*channels));
> 
> reads far outside the 31-entry ams_pl_channels[] array.
> 
> Reject any reg value that would produce an out-of-range ext_chan
> before it is used to index ams_pl_channels[], instead of relying only
> on the upper-bound check.
> 
> Signed-off-by: Manush Prajwal <manushprajwal555@gmail.com>

Explanation seems valid. I'll wait for the AMD folk to have
time to take a look though before considering picking this up.

One comment inline.
> ---
>  drivers/iio/adc/xilinx-ams.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> index 158e6133a..cd778d053 100644
> --- a/drivers/iio/adc/xilinx-ams.c
> +++ b/drivers/iio/adc/xilinx-ams.c
> @@ -1154,8 +1154,11 @@ static int ams_get_ext_chan(struct fwnode_handle *chan_node,
>  		if (ret || reg > AMS_PL_MAX_EXT_CHANNEL + 30)
>  			continue;
>  
> -		chan = &channels[num_channels];
>  		ext_chan = reg + AMS_PL_MAX_FIXED_CHANNEL - 30;
> +		if (ext_chan >= ARRAY_SIZE(ams_pl_channels))
> +			continue;
I haven't looked closely but is it ever fine to go off the top of this?
If not, error out and fail probe.
I'd also prefer to have more direct handling of the wrap around case
rather than relying on it being a big value and so failing this.

Thanks,

Jonathan

> +
> +		chan = &channels[num_channels];
>  		memcpy(chan, &ams_pl_channels[ext_chan], sizeof(*channels));
>  
>  		if (fwnode_property_read_bool(child, "xlnx,bipolar"))


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-06 17:56 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-06 11:05 [PATCH] iio: adc: xilinx-ams: fix OOB read in ams_get_ext_chan() Manush Prajwal
2026-09-06 17:56 ` Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®