[PATCH v2 5/5] ACPI: NFIT: bound the platform capability mask

Pengpeng Hou <[email protected]>
Newsgroups dev.linux.lists.nvdimm,org.kernel.vger.linux-acpi,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The platform capability subtable parser reads highest_capability and
capabilities without first requiring the fixed structure to be present.
It also shifts a signed integer by highest_capability + 1. Firmware can
therefore trigger an out-of-bounds read with a short subtable and an
undefined shift with a value at or above 31.

Require the fixed structure before reading either field. For capability
indices that cover all bits representable by the current u32 field, use
U32_MAX. This ignores capabilities beyond the implemented 32-bit field
rather than rejecting future firmware that advertises a higher index.

Fixes: 06e8ccdab15f ("acpi: nfit: Add support for detect platform CPU cache flush on power loss")
Assisted-by: Codex:gpt-5
Signed-off-by: Pengpeng Hou <[email protected]>
---
 drivers/acpi/nfit/core.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 84c70f1941c5..7638d4dc8c6d 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -987,7 +987,14 @@ static bool add_platform_cap(struct acpi_nfit_desc *acpi_desc,
 	struct device *dev = acpi_desc->dev;
 	u32 mask;
 
-	mask = (1 << (pcap->highest_capability + 1)) - 1;
+	if (pcap->header.length < sizeof(*pcap))
+		return false;
+
+	if (pcap->highest_capability >= 31)
+		mask = U32_MAX;
+	else
+		mask = (1U << (pcap->highest_capability + 1)) - 1;
+
 	acpi_desc->platform_cap = pcap->capabilities & mask;
 	dev_dbg(dev, "cap: %#x\n", acpi_desc->platform_cap);
 	return true;
-- 
2.50.1 (Apple Git-155)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.