* [PATCH v2 0/2] ata: reject invalid DT port numbers in AHCI drivers
@ 2026-11-10 15:03 shao.mingyin
2026-11-10 15:03 ` [PATCH v2 1/2] ata: libahci_platform: reject invalid port numbers shao.mingyin
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: shao.mingyin @ 2026-11-10 15:03 UTC (permalink / raw)
To: dlemoal, cassel, linux-ide; +Cc: hansg, linux-kernel, stable
Both the shared AHCI platform support and the DWC glue use the "reg"
property of their port child nodes as a port number without checking
that it addresses one of the controller's ports.
Patch 1 is in the shared platform code. ahci_platform_get_firmware()
uses "reg" as an index into hpriv->saved_port_cap[] while filling the
firmware-specific port capabilities, so a "reg" value at or above
hpriv->nports writes past that array. Patch 2 is in the DWC glue.
ahci_dwc_init_dmacr() walks the same child nodes a second time and uses
"reg" both as an index into dpriv->dmacr[] and to compute the port MMIO
base, with the same out-of-range consequence.
Both loops now skip child nodes whose "reg" value is at or above
hpriv->nports, matching the check in ahci_platform_get_resources(),
which has already reported the invalid port number. The two patches
are independent and can be applied in any order; each carries Fixes:
and Cc: stable.
Changes in v2:
- Do not print a warning for an invalid port number: the resource loop
has already reported it (Niklas Cassel). The check is unchanged.
- Send the two fixes, previously posted separately, as one series at
Niklas's request.
- 2/2 keeps Damien Le Moal's Reviewed-by from v1, since the only change
is the dropped warning (confirmed by Niklas Cassel).
Link to v1 1/2: https://lore.kernel.org/all/20261029190111138tS0yRo0lL1zJZ_IutobE1@zte.com.cn/
Link to v1 2/2: https://lore.kernel.org/all/20261104221318841yKO89PGcSNeaV4KutBOUJ@zte.com.cn/
Review 1/2: https://lore.kernel.org/all/avHkMosHVOXCpVPD@ryzen/
Review 2/2: https://lore.kernel.org/all/avHknBRJnZPpAIke@ryzen/
Shao Mingyin (2):
ata: libahci_platform: reject invalid port numbers
ata: ahci_dwc: reject invalid DT port numbers
drivers/ata/ahci_dwc.c | 4 ++++
drivers/ata/libahci_platform.c | 4 ++++
2 files changed, 8 insertions(+)
---
base-commit: ddfe51b0a0f5dc9e415cc2c8ad8db17532dd426b
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] ata: libahci_platform: reject invalid port numbers
2026-11-10 15:03 [PATCH v2 0/2] ata: reject invalid DT port numbers in AHCI drivers shao.mingyin
@ 2026-11-10 15:03 ` shao.mingyin
2026-11-10 15:03 ` [PATCH v2 2/2] ata: ahci_dwc: reject invalid DT " shao.mingyin
2026-11-10 20:08 ` [PATCH v2 0/2] ata: reject invalid DT port numbers in AHCI drivers Niklas Cassel
2 siblings, 0 replies; 4+ messages in thread
From: shao.mingyin @ 2026-11-10 15:03 UTC (permalink / raw)
To: dlemoal, cassel, linux-ide; +Cc: hansg, linux-kernel, stable
From: Shao Mingyin <shao.mingyin@zte.com.cn>
ahci_platform_get_firmware() reads the "reg" property of every child
node of the AHCI controller and uses the value as an index into
hpriv->saved_port_cap[], which has AHCI_MAX_PORTS (32) entries, without
checking it first.
ahci_platform_get_resources() checks the same property against
hpriv->nports, but only in its own loop, and hpriv->nports is itself
clamped to AHCI_MAX_PORTS. A device tree describing a port with a
"reg" value of 32 or more therefore reaches
ahci_platform_get_firmware(), where the "hba-port-cap" property is then
written past the end of the array. Values just above the end corrupt
the following fields of struct ahci_host_priv, larger ones write outside
of the devres allocation.
Apply the same validity check as the resource loop and skip such child
nodes. That loop has already reported the invalid port number, so do
not print a second warning.
Fixes: 18ee7c49f75b ("ata: ahci: Introduce firmware-specific caps initialization")
Cc: stable@vger.kernel.org
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
---
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 1/2, with the ahci_dwc patch as 2/2.
- v1: https://lore.kernel.org/all/20261029190111138tS0yRo0lL1zJZ_IutobE1@zte.com.cn/
---
drivers/ata/libahci_platform.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index ae342080556a..0ffa4486de77 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -434,6 +434,10 @@ static int ahci_platform_get_firmware(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;
+
if (!of_property_read_u32(child, "hba-port-cap", &hpriv->saved_port_cap[port]))
hpriv->saved_port_cap[port] &= PORT_CMD_CAP;
}
--
2.27.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] ata: ahci_dwc: reject invalid DT port numbers
2026-11-10 15:03 [PATCH v2 0/2] ata: reject invalid DT port numbers in AHCI drivers shao.mingyin
2026-11-10 15:03 ` [PATCH v2 1/2] ata: libahci_platform: reject invalid port numbers shao.mingyin
@ 2026-11-10 15:03 ` shao.mingyin
2026-11-10 20:08 ` [PATCH v2 0/2] ata: reject invalid DT port numbers in AHCI drivers Niklas Cassel
2 siblings, 0 replies; 4+ messages in thread
From: shao.mingyin @ 2026-11-10 15:03 UTC (permalink / raw)
To: dlemoal, cassel, linux-ide; +Cc: hansg, linux-kernel, stable
From: Shao Mingyin <shao.mingyin@zte.com.cn>
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@vger.kernel.org
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
---
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@zte.com.cn/
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
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 0/2] ata: reject invalid DT port numbers in AHCI drivers
2026-11-10 15:03 [PATCH v2 0/2] ata: reject invalid DT port numbers in AHCI drivers shao.mingyin
2026-11-10 15:03 ` [PATCH v2 1/2] ata: libahci_platform: reject invalid port numbers shao.mingyin
2026-11-10 15:03 ` [PATCH v2 2/2] ata: ahci_dwc: reject invalid DT " shao.mingyin
@ 2026-11-10 20:08 ` Niklas Cassel
2 siblings, 0 replies; 4+ messages in thread
From: Niklas Cassel @ 2026-11-10 20:08 UTC (permalink / raw)
To: dlemoal, linux-ide, shao.mingyin; +Cc: hansg, linux-kernel, stable
On Tue, 10 Nov 2026 23:03:27 +0800, shao.mingyin@zte.com.cn wrote:
> Both the shared AHCI platform support and the DWC glue use the "reg"
> property of their port child nodes as a port number without checking
> that it addresses one of the controller's ports.
>
> Patch 1 is in the shared platform code. ahci_platform_get_firmware()
> uses "reg" as an index into hpriv->saved_port_cap[] while filling the
> firmware-specific port capabilities, so a "reg" value at or above
> hpriv->nports writes past that array. Patch 2 is in the DWC glue.
> ahci_dwc_init_dmacr() walks the same child nodes a second time and uses
> "reg" both as an index into dpriv->dmacr[] and to compute the port MMIO
> base, with the same out-of-range consequence.
>
> [...]
Applied to libata/linux.git (for-7.5), thanks!
[1/2] ata: libahci_platform: reject invalid port numbers
https://git.kernel.org/libata/linux/c/b10c7a1c
[2/2] ata: ahci_dwc: reject invalid DT port numbers
https://git.kernel.org/libata/linux/c/0f7d0044
Kind regards,
Niklas
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-10 20:08 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-10 15:03 [PATCH v2 0/2] ata: reject invalid DT port numbers in AHCI drivers shao.mingyin
2026-11-10 15:03 ` [PATCH v2 1/2] ata: libahci_platform: reject invalid port numbers shao.mingyin
2026-11-10 15:03 ` [PATCH v2 2/2] ata: ahci_dwc: reject invalid DT " shao.mingyin
2026-11-10 20:08 ` [PATCH v2 0/2] ata: reject invalid DT port numbers in AHCI drivers Niklas Cassel
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®