[PATCH v2 2/2] ata: ahci_dwc: reject invalid DT port numbers

From: shao.mingyin

Date: Tue Nov 10 2026 - 12:43:50 EST


From: Shao Mingyin <shao.mingyin@xxxxxxxxxx>

ahci_dwc_init_dmacr() reads the "reg" property of every available child
node and uses it directly as a port number, both to compute the port
MMIO base and as an index into dpriv->dmacr[], which has AHCI_MAX_PORTS
entries. ahci_platform_get_resources(), which runs earlier, checks the
same property against hpriv->nports and skips invalid child nodes, but
this second walk does not.

A device tree that describes one valid port and one port with a "reg"
value above AHCI_MAX_PORTS therefore makes the driver write past
dpriv->dmacr[] and access MMIO beyond the mapped region. Apply the same
check as the resource loop and skip invalid child nodes. That loop has
already reported the invalid port number, so do not print a second
warning.

Fixes: 33629d35090f ("ata: ahci: Add DWC AHCI SATA controller support")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Shao Mingyin <shao.mingyin@xxxxxxxxxx>
Reviewed-by: Damien Le Moal <dlemoal@xxxxxxxxxx>

---
v2:
- Do not print a warning for the invalid port number: the resource loop
has already reported it (Niklas Cassel). The validity check itself
is unchanged.
- Send as 2/2, with the libahci_platform patch as 1/2.
- Carry Damien Le Moal's Reviewed-by from v1: the only code change is
dropping the redundant warning (confirmed by Niklas Cassel).
- v1: https://lore.kernel.org/all/20261104221318841yKO89PGcSNeaV4KutBOUJ@xxxxxxxxxx/

Tested on 7.3.0-next-20261030 (QEMU/TCG arm64 guest, KASAN) with a
TEST-ONLY device tree. The DT adds a snps,dwc-ahci node with port@0
and port@100; the TEST-ONLY printk hook in ahci_dwc_init_dmacr() is
applied to both kernels. mem=512M keeps the fake MMIO window outside
System RAM.

unpatched patched
KASAN: slab-out-of-bounds no KASAN report
in ahci_dwc_probe port 100 skipped, boot
---
drivers/ata/ahci_dwc.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/ata/ahci_dwc.c b/drivers/ata/ahci_dwc.c
index feb8a8539b8e..0ace0baa2b94 100644
--- a/drivers/ata/ahci_dwc.c
+++ b/drivers/ata/ahci_dwc.c
@@ -225,6 +225,10 @@ static int ahci_dwc_init_dmacr(struct ahci_host_priv *hpriv)
if (of_property_read_u32(child, "reg", &port))
return -EINVAL;

+ /* Already reported by ahci_platform_get_resources() */
+ if (port >= hpriv->nports)
+ continue;
+
port_mmio = __ahci_port_base(hpriv, port);
dmacr = readl(port_mmio + AHCI_DWC_PORT_DMACR);

--
2.27.0