[PATCH v2 3/7] ACPI: extlog: Avoid populating software AER metadata from raw hardware buffer
Dave Jiang <[email protected]>
| Newsgroups | org.kernel.vger.linux-cxl,org.kernel.vger.linux-acpi |
|---|---|
| Message-ID | <[email protected]> |
extlog_print_pcie() casts pcie_err->aer_info directly to struct
aer_capability_regs *, treating raw hardware register bytes as the
struct's software-only metadata fields header_log.header_len and
header_log.flit.
struct aer_capability_regs embeds struct pcie_tlp_log, which places
header_len and flit after the 14-element dw[] array at offset 84.
The 96-byte aer_info hardware buffer covers that offset, so the cast
populates header_len and flit with unvalidated hardware data.
pcie_print_tlp_log() uses flit and header_len to bound a loop over
dw[]. If flit is set and header_len reads as a large value, the loop
iterates past the end of the dw[] array.
Copy aer_info into a zeroed local struct aer_capability_regs and
explicitly clear header_len and flit after the copy so only known-safe
values reach pcie_print_tlp_log().
Fixes: e778ffefa34d ("ACPI: extlog: Trace CPER PCI Express Error Section")
Link: https://lore.kernel.org/linux-cxl/[email protected]/
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Dave Jiang <[email protected]>
---
v2:
- new patch, issue raised by sashiko
---
drivers/acpi/acpi_extlog.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 06a944dadbc1..fbc88c584c06 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -137,6 +137,7 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
int severity)
{
#ifdef ACPI_APEI_PCIEAER
+ struct aer_capability_regs aer_regs = {};
struct aer_capability_regs *aer;
struct pci_dev *pdev;
unsigned int devfn;
@@ -149,7 +150,12 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
return;
aer_severity = cper_severity_to_aer(severity);
- aer = (struct aer_capability_regs *)pcie_err->aer_info;
+
+ memcpy(&aer_regs, pcie_err->aer_info, sizeof(pcie_err->aer_info));
+ aer_regs.header_log.header_len = 0;
+ aer_regs.header_log.flit = false;
+ aer = &aer_regs;
+
domain = pcie_err->device_id.segment;
bus = pcie_err->device_id.bus;
devfn = PCI_DEVFN(pcie_err->device_id.device,
--
2.55.0