* [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko
@ 2026-09-04 17:23 Dave Jiang
2026-09-04 17:23 ` [PATCH v6 01/13] efi/cper: Reject CPER records with an out-of-range error_data_length Dave Jiang
` (13 more replies)
0 siblings, 14 replies; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, Jonathan Cameron
Fixes for pre-existing issues sashiko-bot found while reviewing patches in the
CPER, extlog and GHES paths. v1 through v3 fixed successive batches as the
review widened; see the links below.
The series is grouped in three parts, plus a cleanup.
Bound the record before anything walks it:
1/13: Reject CPER records with an out-of-range error_data_length.
2/13: Reject an error status block length that wraps a u32.
3/13: Validate the extlog record length before walking sections.
Fix the extlog error paths, then enable them:
4/13: Defer CXL protocol error handling to avoid a lock inversion.
5/13: Avoid populating software AER metadata from the raw hardware buffer.
6/13: Validate the PCIe error section length before payload access.
7/13: Fix the CONFIG_ACPI_APEI_PCIEAER guard typo in extlog.c.
Bound each section payload before its consumers read it:
8/13: Bound the CXL event record copy to the firmware section length.
9/13: Validate the CXL protocol error section length before the RAS cap copy.
10/13: Read only validated fields in cper_mem_err_pack().
11/13: Validate the memory error section length before payload access.
12/13: Bound the AER info copy and sanitize software metadata in ghes.c.
Then drop an export patch 4 made redundant:
13/13: Make cxl_cper_handle_prot_err() static.
Patches 1, 2 and 10 touch drivers/firmware/efi/cper.c, closing the holes at
the shared choke point the rest of the series relies on. Patch 2 also fixes an
infinite loop in bert_print_all(), unrelated to this series but the same root
cause.
Known gaps, left for separate patches:
- cxl_cper_print_prot_err() in drivers/firmware/efi/cper_cxl.c uses
dvsec_len without bounding it against the section length.
- cxl_rch_get_aer_info() in drivers/cxl/core/ras_rch.c reads the RCH AER
capability from MMIO without clearing header_len/flit, the same class as
patches 5 and 12. In the same file, cxl_rch_get_aer_severity() tests
PCI_ERR_ROOT_FATAL_RCV against uncor_status, where that bit is
PCI_ERR_UNC_FCP.
- struct pcie_tlp_log grew to 60 bytes for Flit mode, so the 96-byte CPER
AER info no longer maps 1:1 onto struct aer_capability_regs past the
Header Log. Patches 5 and 12 now copy the part that maps and place the TLP
Prefix Log from its own offset, which covers every field the print path
reads - but nothing here decodes the Flit-mode header DWORDs, which reuse
those same prefix registers at payload offset 56 while the struct expects
dw[4..13] at 44. Doing that properly wants a field-by-field mapping
shared with cxl_rch_get_aer_info(), plus a clamp: pcie_print_tlp_log()
trusts header_len against a 14-entry dw[], and PCI_ERR_CAP_TLP_LOG_SIZE
is five bits wide.
v1: https://lore.kernel.org/linux-cxl/20260709162807.1957783-1-dave.jiang@intel.com/
v2: https://lore.kernel.org/linux-cxl/20260714231835.303081-1-dave.jiang@intel.com/
v3: https://lore.kernel.org/linux-cxl/20260717161647.1493259-1-dave.jiang@intel.com/
v4: https://lore.kernel.org/linux-cxl/20260824174936.939059-1-dave.jiang@intel.com/
v5: https://lore.kernel.org/linux-cxl/20260827203726.3027541-1-dave.jiang@intel.com/
Changes since v5
----------------
- Patches 5 and 12: also place the TLP Prefix Log from its own hardware
offset rather than leaving it zero. Shortening the copy in v5 dropped it,
and it is the one field the print path still reads (sashiko). Alison's and
Shuai's Reviewed-by are kept on both, since the intent and location have
not changed.
Changes since v4
----------------
- Patch 1: use check_add_overflow() instead of a u64 sum plus an INT_MAX
test, and drop the now-redundant acpi_hest_get_size() bound, since
record_size is never smaller than the header (Jonathan Cameron).
- Patches 5 and 12: copy only the 44 bytes of aer_info that map onto struct
aer_capability_regs - the leading registers and the four Header Log DWORDs
- and leave the rest zero, instead of copying all 96 bytes and then
clearing header_len and flit (Jonathan Cameron). That also keeps the Root
Error Command, Root Error Status and Error Source ID out of
header_log.prefix[], where pcie_print_tlp_log() was printing them as
end-to-end prefixes.
- Patch 3: kept the length bound ahead of cper_estatus_check() and expanded
the comment to say why. Swapping them would let cper_estatus_check() walk
sections over an unbounded data_length, past the end of elog_buf
(Jonathan Cameron).
- Condensed the commit logs and comments again; prose only.
Changes since v3
----------------
- Regrouped into three parts: bound the record, fix and enable the extlog
paths, then bound each section payload. v3 interleaved them, so patch 1
checked a section before the patch establishing that contract. No code
changed.
- Moved the extlog lock inversion fix (patch 4) ahead of the CXL protocol
error length validation (patch 9). The former deletes
extlog_cxl_cper_handle_prot_err(), which the v3 order plumbed a new len
argument through three patches before removing it. No functional change.
- Patch 1: bound the sum rather than the u32 error_data_length, so the check
does not depend on the <acpi/ghes.h> helpers behaving. The v3 "< 0" check
was dead code (Tony Luck, Shuai Xue). Reviewed-by dropped; not the same
check.
- New patch 2: reject an error status block length that wraps the u32 sum in
cper_estatus_len(). A data_length of 0xffffffec makes it read back as 0,
slipping past the extlog bound in patch 3 and leaving bert_print_all()
advancing by zero forever (sashiko).
- Patch 4: moved the cxl_cper_post_prot_err() declaration inside the
CONFIG_ACPI_APEI_GHES block in <acpi/ghes.h> (Shuai Xue).
- Patch 6: warn instead of returning silently on a short PCIe section (Shuai
Xue), and added the Closes: link v3 omitted.
- Patch 7: corrected the Fixes tag to e778ffefa34d, the commit that added the
"#ifdef ACPI_APEI_PCIEAER" guard, and dropped its Reported-by; sashiko-bot
reviewed that patch rather than reporting the typo.
- Patch 9: made the two prot-err length messages distinguishable; both printed
the same text. The second now reports dvsec_len (Shuai Xue).
- New patch 10: read only validated fields in cper_mem_err_pack(). It copied
extended, rank, mem_array_handle and mem_dev_handle unconditionally from
offsets 73 to 79, past the end of the 73-byte UEFI 2.1/2.2 layout (sashiko).
- Patch 11: derive the required length from the claimed validation bits. A
single size gets it wrong both ways (sashiko). Reviewed-by dropped; the
check gained a helper and is no longer the one Alison and Shuai reviewed.
- New patch 13: make cxl_cper_handle_prot_err() static. Patch 4 removed its
last external caller.
Dave Jiang (13):
efi/cper: Reject CPER records with an out-of-range error_data_length
efi/cper: Reject an error status block length that wraps a u32
ACPI: extlog: Validate elog record length before walking sections
ACPI: extlog: Defer CXL protocol error handling to avoid lock
inversion
ACPI: extlog: Avoid populating software AER metadata from raw hardware
buffer
ACPI: extlog: Validate PCIe error section length before payload access
ACPI: extlog: Fix CONFIG_ACPI_APEI_PCIEAER guard typo
ACPI: APEI: GHES: Bound CXL event record copy to the firmware section
length
ACPI: APEI: GHES: Validate CXL protocol error section length before
RAS cap copy
efi/cper: Read only validated fields in cper_mem_err_pack()
ACPI: APEI: GHES: Validate memory error section length before payload
access
ACPI: APEI: GHES: Bound AER info copy and sanitize software metadata
cxl/ras: Make cxl_cper_handle_prot_err() static
drivers/acpi/acpi_extlog.c | 64 +++++++++++++---------
drivers/acpi/apei/ghes.c | 92 +++++++++++++++++++++++++++-----
drivers/acpi/apei/ghes_helpers.c | 18 ++++++-
drivers/cxl/core/ras.c | 3 +-
drivers/firmware/efi/cper.c | 51 +++++++++++++++---
include/acpi/ghes.h | 4 ++
include/cxl/event.h | 6 +--
7 files changed, 186 insertions(+), 52 deletions(-)
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
--
2.54.0
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v6 01/13] efi/cper: Reject CPER records with an out-of-range error_data_length
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 17:39 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 02/13] efi/cper: Reject an error status block length that wraps a u32 Dave Jiang
` (12 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot
cper_estatus_check() sizes each section with acpi_hest_get_record_size(),
which adds the firmware-controlled u32 error_data_length to the header size
as a signed int (see <acpi/ghes.h>). A value in the top sizeof(*gdata)
bytes of the u32 range wraps the sum small rather than large, so it slips
past the "record_size > data_len" check: against the 72-byte v300 header,
0xffffffb9 sizes the record at 1 and acpi_hest_get_next() walks it a byte
at a time, off the end. 0xffffffb8 sizes it at 0 and loops forever.
Use check_add_overflow() to reject a sum that will not fit the int those
helpers return, since the walk advances by that value. That subsumes the
"acpi_hest_get_size(gdata) > data_len" test above it, because record_size
is never smaller than the header.
The later "len < sizeof(*foo)" guards rely on this per-section upper bound;
they are lower bounds only.
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=1
Fixes: 45b14a4ffcc1 ("efi: cper: Fix possible out-of-bounds access")
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/firmware/efi/cper.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 06b4fdb59917..332c78f2d561 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -752,7 +752,7 @@ EXPORT_SYMBOL_GPL(cper_estatus_check_header);
int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
{
struct acpi_hest_generic_data *gdata;
- unsigned int data_len, record_size;
+ unsigned int data_len;
int rc;
rc = cper_estatus_check_header(estatus);
@@ -762,10 +762,18 @@ int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
data_len = estatus->data_length;
apei_estatus_for_each_section(estatus, gdata) {
- if (acpi_hest_get_size(gdata) > data_len)
+ int record_size;
+
+ /*
+ * The <acpi/ghes.h> helpers sum these as a signed int, so a
+ * huge error_data_length wraps small rather than large and the
+ * walk then advances by that wrapped value. Reject a size an
+ * int cannot carry.
+ */
+ if (check_add_overflow(acpi_hest_get_size(gdata),
+ gdata->error_data_length, &record_size))
return -EINVAL;
- record_size = acpi_hest_get_record_size(gdata);
if (record_size > data_len)
return -EINVAL;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 02/13] efi/cper: Reject an error status block length that wraps a u32
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
2026-09-04 17:23 ` [PATCH v6 01/13] efi/cper: Reject CPER records with an out-of-range error_data_length Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 17:38 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 03/13] ACPI: extlog: Validate elog record length before walking sections Dave Jiang
` (11 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot,
Jonathan Cameron
cper_estatus_len() sums the firmware-controlled data_length (or
raw_data_offset plus raw_data_length) into a u32. A data_length of
0xffffffec wraps that sum to 0, and a length that reads back short defeats
every bound built on it: bert_print_all() passes its "remain <
estatus_len" check, then advances "estatus += estatus_len" by zero and
loops forever. GHES survives only because __ghes_check_estatus() rejects a
length below sizeof(*estatus) first.
Reject a length that cannot be expressed in a u32 in
cper_estatus_check_header(), which both of today's callers reach: GHES via
__ghes_check_estatus() and BERT via cper_estatus_check(). extlog reaches
neither yet; a later patch routes it through cper_estatus_check(), whose
ELOG_ENTRY_LEN bound needs this to hold.
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=1
Fixes: 06d65deade9a ("ACPI, APEI, UEFI Common Platform Error Record (CPER) header")
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/firmware/efi/cper.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 332c78f2d561..3dcef618ad39 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -745,6 +745,17 @@ int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus)
estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
return -EINVAL;
+ /*
+ * cper_estatus_len() sums these into a u32, and a wrapped sum reads
+ * back smaller than the record. Reject a length that cannot be
+ * expressed so no caller is handed the short value.
+ */
+ if ((u64)sizeof(*estatus) + estatus->data_length > U32_MAX)
+ return -EINVAL;
+ if (estatus->raw_data_length &&
+ (u64)estatus->raw_data_offset + estatus->raw_data_length > U32_MAX)
+ return -EINVAL;
+
return 0;
}
EXPORT_SYMBOL_GPL(cper_estatus_check_header);
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 03/13] ACPI: extlog: Validate elog record length before walking sections
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
2026-09-04 17:23 ` [PATCH v6 01/13] efi/cper: Reject CPER records with an out-of-range error_data_length Dave Jiang
2026-09-04 17:23 ` [PATCH v6 02/13] efi/cper: Reject an error status block length that wraps a u32 Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 17:40 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 04/13] ACPI: extlog: Defer CXL protocol error handling to avoid lock inversion Dave Jiang
` (10 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot
extlog_print() copies a fixed ELOG_ENTRY_LEN (4096) bytes from the elog
record into elog_buf, then walks the sections using the firmware-controlled
data_length. Nothing keeps data_length inside the buffer, so a malformed
record walks the section pointer past elog_buf and reads adjacent memory.
Unlike the GHES paths, extlog never calls cper_estatus_check().
Reject a record longer than ELOG_ENTRY_LEN and run cper_estatus_check()
before walking the sections. The length test alone is not enough: a wrapped
length reads back short and passes it, which cper_estatus_check() catches
via the header check added earlier. Drop a malformed record with
NOTIFY_DONE and without MCE_HANDLED_EXTLOG, since extlog did not consume
it.
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=6
Fixes: f6ec01da40e4 ("ACPI: extlog: Handle multiple records")
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/acpi/acpi_extlog.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 7ad3b36013cc..046e92ee195f 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -208,6 +208,15 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
tmp = (struct acpi_hest_generic_status *)elog_buf;
+ /*
+ * Bound the length before cper_estatus_check() walks the sections: it
+ * iterates over data_length, which is not yet known to fit elog_buf.
+ * cper_estatus_check_header() then rejects a length that wrapped, which
+ * the bound cannot see.
+ */
+ if (cper_estatus_len(tmp) > ELOG_ENTRY_LEN || cper_estatus_check(tmp))
+ return NOTIFY_DONE;
+
if (!ras_userspace_consumers()) {
print_extlog_rcd(NULL, tmp, cpu);
goto out;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 04/13] ACPI: extlog: Defer CXL protocol error handling to avoid lock inversion
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (2 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 03/13] ACPI: extlog: Validate elog record length before walking sections Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 17:23 ` [PATCH v6 05/13] ACPI: extlog: Avoid populating software AER metadata from raw hardware buffer Dave Jiang
` (9 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot,
Jonathan Cameron
extlog_print() calls cxl_cper_handle_prot_err() synchronously while the
MCE notifier chain rwsem is held, and that path takes the PCI device_lock
via guard(device)(). The probe path takes the two in the opposite order,
holding device_lock while mce_register_decode_chain() takes the rwsem, so
they can deadlock AB-BA.
ghes.c already avoids this by posting protocol errors to a kfifo and
handling them from a workqueue via cxl_cper_post_prot_err(). Export that
function and call it instead.
Declare it with the other CONFIG_ACPI_APEI_GHES exports rather than at the
end of the header. No #else stub: ACPI_EXTLOG selects ACPI_APEI_GHES, so
the only caller cannot exist without it.
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/linux-cxl/20260709165457.8BA181F000E9@smtp.kernel.org/
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/acpi/acpi_extlog.c | 21 ++-------------------
drivers/acpi/apei/ghes.c | 5 +++--
include/acpi/ghes.h | 4 ++++
3 files changed, 9 insertions(+), 21 deletions(-)
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 046e92ee195f..2451362e696d 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -163,23 +163,6 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
#endif
}
-static void
-extlog_cxl_cper_handle_prot_err(struct cxl_cper_sec_prot_err *prot_err,
- int severity)
-{
-#ifdef ACPI_APEI_PCIEAER
- struct cxl_cper_prot_err_work_data wd;
-
- if (cxl_cper_sec_prot_err_valid(prot_err))
- return;
-
- if (cxl_cper_setup_prot_err_work_data(&wd, prot_err, severity))
- return;
-
- cxl_cper_handle_prot_err(&wd);
-#endif
-}
-
static int extlog_print(struct notifier_block *nb, unsigned long val,
void *data)
{
@@ -244,8 +227,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
struct cxl_cper_sec_prot_err *prot_err =
acpi_hest_get_payload(gdata);
- extlog_cxl_cper_handle_prot_err(prot_err,
- gdata->error_severity);
+ cxl_cper_post_prot_err(prot_err,
+ gdata->error_severity);
} else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata);
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index fe10ab0e02f6..83558bb10be1 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -752,8 +752,8 @@ static DEFINE_KFIFO(cxl_cper_prot_err_fifo, struct cxl_cper_prot_err_work_data,
static DEFINE_RAW_SPINLOCK(cxl_cper_prot_err_work_lock);
struct work_struct *cxl_cper_prot_err_work;
-static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
- int severity)
+void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
+ int severity)
{
#ifdef CONFIG_ACPI_APEI_PCIEAER
struct cxl_cper_prot_err_work_data wd;
@@ -777,6 +777,7 @@ static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
schedule_work(cxl_cper_prot_err_work);
#endif
}
+EXPORT_SYMBOL_FOR_MODULES(cxl_cper_post_prot_err, "acpi_extlog");
void cxl_cper_register_prot_err_work(struct work_struct *work)
{
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 8d7e5caef3f1..be496bc0386f 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -85,6 +85,10 @@ int devm_ghes_register_vendor_record_notifier(struct device *dev,
struct list_head *ghes_get_devices(void);
void ghes_estatus_pool_region_free(unsigned long addr, u32 size);
+
+struct cxl_cper_sec_prot_err;
+void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
+ int severity);
#else
static inline struct list_head *ghes_get_devices(void) { return NULL; }
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 05/13] ACPI: extlog: Avoid populating software AER metadata from raw hardware buffer
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (3 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 04/13] ACPI: extlog: Defer CXL protocol error handling to avoid lock inversion Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 17:58 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 06/13] ACPI: extlog: Validate PCIe error section length before payload access Dave Jiang
` (8 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot
extlog_print_pcie() casts pcie_err->aer_info straight to struct
aer_capability_regs *. That struct embeds struct pcie_tlp_log, whose
software-only header_len and flit fields sit at offset 84 - inside the
96-byte aer_info buffer - so the cast fills them with raw firmware bytes.
pcie_print_tlp_log() uses both to bound a loop over dw[], and a large
header_len walks past the end of the array.
Copy into a zeroed local struct, and only as far as aer_info maps onto it:
the leading registers and the four Header Log DWORDs. Place the TLP Prefix
Log separately, from the offset the hardware keeps it at. The rest stays
zero, which covers header_len and flit and keeps the Root Error registers
out of the prefix log, where pcie_print_tlp_log() would print them as
end-to-end prefixes.
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/linux-cxl/20260709165457.8BA181F000E9@smtp.kernel.org/
Fixes: e778ffefa34d ("ACPI: extlog: Trace CPER PCI Express Error Section")
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
v6:
- Also place the TLP Prefix Log from its own hardware offset rather than
leaving it zero. It is the one field the print path reads that the
shortened copy missed (sashiko).
---
drivers/acpi/acpi_extlog.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 2451362e696d..1b61788abd5a 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -137,7 +137,7 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
int severity)
{
#ifdef ACPI_APEI_PCIEAER
- struct aer_capability_regs *aer;
+ struct aer_capability_regs aer_regs = {};
struct pci_dev *pdev;
unsigned int devfn;
unsigned int bus;
@@ -149,7 +149,21 @@ 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;
+
+ /*
+ * struct pcie_tlp_log is larger than the hardware layout, so aer_info
+ * only maps onto the struct up to the four Header Log DWORDs. Copy that
+ * much, then place the TLP Prefix Log from where the hardware keeps it.
+ * Everything else stays zero: nothing reads root_command, root_status or
+ * the error source IDs, and header_len and flit are software-only.
+ */
+ memcpy(&aer_regs, pcie_err->aer_info,
+ offsetof(struct aer_capability_regs, header_log) +
+ PCIE_STD_NUM_TLP_HEADERLOG * sizeof(u32));
+ memcpy(aer_regs.header_log.prefix,
+ pcie_err->aer_info + PCI_ERR_PREFIX_LOG,
+ sizeof(aer_regs.header_log.prefix));
+
domain = pcie_err->device_id.segment;
bus = pcie_err->device_id.bus;
devfn = PCI_DEVFN(pcie_err->device_id.device,
@@ -158,7 +172,7 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
if (!pdev)
return;
- pci_print_aer(pdev, aer_severity, aer);
+ pci_print_aer(pdev, aer_severity, &aer_regs);
pci_dev_put(pdev);
#endif
}
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 06/13] ACPI: extlog: Validate PCIe error section length before payload access
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (4 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 05/13] ACPI: extlog: Avoid populating software AER metadata from raw hardware buffer Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 17:23 ` [PATCH v6 07/13] ACPI: extlog: Fix CONFIG_ACPI_APEI_PCIEAER guard typo Dave Jiang
` (7 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot,
Jonathan Cameron
extlog_print_pcie() reads pcie_err->validation_bits and device_id and
copies the 96-byte aer_info buffer without checking that
gdata->error_data_length is big enough for a struct cper_sec_pcie. The
cper_estatus_check() call added earlier keeps the read inside the estatus
block, but a short section still gets stale adjacent bytes treated as PCIe
error data.
Reject a section too small to hold the record before touching any field,
and warn: a truncated section means firmware is emitting malformed records.
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/linux-cxl/20260709165457.8BA181F000E9@smtp.kernel.org/
Fixes: e778ffefa34d ("ACPI: extlog: Trace CPER PCI Express Error Section")
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/acpi/acpi_extlog.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 1b61788abd5a..0ab7885e5471 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -134,7 +134,7 @@ static int print_extlog_rcd(const char *pfx,
}
static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
- int severity)
+ int severity, u32 len)
{
#ifdef ACPI_APEI_PCIEAER
struct aer_capability_regs aer_regs = {};
@@ -144,6 +144,12 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
int aer_severity;
int domain;
+ if (len < sizeof(*pcie_err)) {
+ pr_warn_ratelimited(FW_WARN
+ "PCIe error section too small (%u)\n", len);
+ return;
+ }
+
if (!(pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID &&
pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO))
return;
@@ -246,7 +252,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
} else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata);
- extlog_print_pcie(pcie_err, gdata->error_severity);
+ extlog_print_pcie(pcie_err, gdata->error_severity,
+ gdata->error_data_length);
} else {
void *err = acpi_hest_get_payload(gdata);
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 07/13] ACPI: extlog: Fix CONFIG_ACPI_APEI_PCIEAER guard typo
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (5 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 06/13] ACPI: extlog: Validate PCIe error section length before payload access Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 17:23 ` [PATCH v6 08/13] ACPI: APEI: GHES: Bound CXL event record copy to the firmware section length Dave Jiang
` (6 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, Jonathan Cameron
The guard reads "#ifdef ACPI_APEI_PCIEAER" rather than
"#ifdef CONFIG_ACPI_APEI_PCIEAER". That symbol is never defined, so the
extlog PCIe AER handling is always compiled out.
Use the CONFIG_ prefixed symbol.
Fixes: e778ffefa34d ("ACPI: extlog: Trace CPER PCI Express Error Section")
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/acpi/acpi_extlog.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 0ab7885e5471..8c17c2719526 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -136,7 +136,7 @@ static int print_extlog_rcd(const char *pfx,
static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
int severity, u32 len)
{
-#ifdef ACPI_APEI_PCIEAER
+#ifdef CONFIG_ACPI_APEI_PCIEAER
struct aer_capability_regs aer_regs = {};
struct pci_dev *pdev;
unsigned int devfn;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 08/13] ACPI: APEI: GHES: Bound CXL event record copy to the firmware section length
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (6 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 07/13] ACPI: extlog: Fix CONFIG_ACPI_APEI_PCIEAER guard typo Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 17:23 ` [PATCH v6 09/13] ACPI: APEI: GHES: Validate CXL protocol error section length before RAS cap copy Dave Jiang
` (5 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot,
Jonathan Cameron
cxl_cper_post_event() copies a fixed sizeof(struct cxl_cper_event_rec)
out of the firmware CPER section without checking how long the section
actually is, so a short one reads past the record.
Pass gdata->error_data_length in and reject a section too small to hold
the record before the copy.
Reported-by: sashiko-bot@kernel.org
Link: https://sashiko.dev/#/patchset/20260617-topics-ahmtib01-ras_ffh_arm_internal_review-v6-0-91f725174aa0@arm.com?part=6
Fixes: 5e4a264bf8b5 ("acpi/ghes: Process CXL Component Events")
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/acpi/apei/ghes.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 83558bb10be1..8f66dfb8edba 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -824,10 +824,15 @@ static DEFINE_RAW_SPINLOCK(cxl_cper_work_lock);
struct work_struct *cxl_cper_work;
static void cxl_cper_post_event(enum cxl_event_type event_type,
- struct cxl_cper_event_rec *rec)
+ struct cxl_cper_event_rec *rec, u32 len)
{
struct cxl_cper_work_data wd;
+ if (len < sizeof(*rec)) {
+ pr_err(FW_WARN "CXL CPER section too small (%u)\n", len);
+ return;
+ }
+
if (rec->hdr.length <= sizeof(rec->hdr) ||
rec->hdr.length > sizeof(*rec)) {
pr_err(FW_WARN "CXL CPER Invalid section length (%u)\n",
@@ -964,15 +969,18 @@ static void ghes_do_proc(struct ghes *ghes,
} else if (guid_equal(sec_type, &CPER_SEC_CXL_GEN_MEDIA_GUID)) {
struct cxl_cper_event_rec *rec = acpi_hest_get_payload(gdata);
- cxl_cper_post_event(CXL_CPER_EVENT_GEN_MEDIA, rec);
+ cxl_cper_post_event(CXL_CPER_EVENT_GEN_MEDIA, rec,
+ gdata->error_data_length);
} else if (guid_equal(sec_type, &CPER_SEC_CXL_DRAM_GUID)) {
struct cxl_cper_event_rec *rec = acpi_hest_get_payload(gdata);
- cxl_cper_post_event(CXL_CPER_EVENT_DRAM, rec);
+ cxl_cper_post_event(CXL_CPER_EVENT_DRAM, rec,
+ gdata->error_data_length);
} else if (guid_equal(sec_type, &CPER_SEC_CXL_MEM_MODULE_GUID)) {
struct cxl_cper_event_rec *rec = acpi_hest_get_payload(gdata);
- cxl_cper_post_event(CXL_CPER_EVENT_MEM_MODULE, rec);
+ cxl_cper_post_event(CXL_CPER_EVENT_MEM_MODULE, rec,
+ gdata->error_data_length);
} else {
void *err = acpi_hest_get_payload(gdata);
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 09/13] ACPI: APEI: GHES: Validate CXL protocol error section length before RAS cap copy
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (7 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 08/13] ACPI: APEI: GHES: Bound CXL event record copy to the firmware section length Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 18:05 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 10/13] efi/cper: Read only validated fields in cper_mem_err_pack() Dave Jiang
` (4 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot,
Jonathan Cameron
cxl_cper_setup_prot_err_work_data() locates the RAS Capability block at
prot_err + sizeof(*prot_err) + dvsec_len and copies it, but dvsec_len is
firmware controlled and never validated, so it can point the copy outside
the section.
Extend cxl_cper_sec_prot_err_valid() to check that the section can hold
the header, and that the header, DVSEC and RAS Capability block together
fit the reported section length.
Reported-by: sashiko-bot@kernel.org
Link: https://sashiko.dev/#/patchset/20260617-topics-ahmtib01-ras_ffh_arm_internal_review-v6-0-91f725174aa0@arm.com?part=6
Link: https://lore.kernel.org/linux-cxl/20260709165457.8BA181F000E9@smtp.kernel.org/
Fixes: 315c2f0b53ba ("acpi/ghes, cper: Recognize and cache CXL Protocol errors")
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/acpi/acpi_extlog.c | 3 ++-
drivers/acpi/apei/ghes.c | 7 ++++---
drivers/acpi/apei/ghes_helpers.c | 18 +++++++++++++++++-
include/acpi/ghes.h | 2 +-
include/cxl/event.h | 4 ++--
5 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 8c17c2719526..9e61354a807b 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -248,7 +248,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
acpi_hest_get_payload(gdata);
cxl_cper_post_prot_err(prot_err,
- gdata->error_severity);
+ gdata->error_severity,
+ gdata->error_data_length);
} else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata);
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 8f66dfb8edba..111895c57c2f 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -753,12 +753,12 @@ static DEFINE_RAW_SPINLOCK(cxl_cper_prot_err_work_lock);
struct work_struct *cxl_cper_prot_err_work;
void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
- int severity)
+ int severity, u32 len)
{
#ifdef CONFIG_ACPI_APEI_PCIEAER
struct cxl_cper_prot_err_work_data wd;
- if (cxl_cper_sec_prot_err_valid(prot_err))
+ if (cxl_cper_sec_prot_err_valid(prot_err, len))
return;
guard(raw_spinlock_irqsave)(&cxl_cper_prot_err_work_lock);
@@ -965,7 +965,8 @@ static void ghes_do_proc(struct ghes *ghes,
} else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) {
struct cxl_cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata);
- cxl_cper_post_prot_err(prot_err, gdata->error_severity);
+ cxl_cper_post_prot_err(prot_err, gdata->error_severity,
+ gdata->error_data_length);
} else if (guid_equal(sec_type, &CPER_SEC_CXL_GEN_MEDIA_GUID)) {
struct cxl_cper_event_rec *rec = acpi_hest_get_payload(gdata);
diff --git a/drivers/acpi/apei/ghes_helpers.c b/drivers/acpi/apei/ghes_helpers.c
index bc7111b740af..df41b993f413 100644
--- a/drivers/acpi/apei/ghes_helpers.c
+++ b/drivers/acpi/apei/ghes_helpers.c
@@ -5,8 +5,15 @@
#include <linux/aer.h>
#include <cxl/event.h>
-int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
+int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err, u32 len)
{
+ if (len < sizeof(*prot_err)) {
+ pr_err_ratelimited(FW_WARN
+ "CXL CPER prot err section too small (%u)\n",
+ len);
+ return -EINVAL;
+ }
+
if (!(prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS)) {
pr_err_ratelimited("CXL CPER invalid agent type\n");
return -EINVAL;
@@ -23,6 +30,15 @@ int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
return -EINVAL;
}
+ /* The RAS Capability block sits after a firmware-sized DVSEC. */
+ if (sizeof(*prot_err) + prot_err->dvsec_len +
+ sizeof(struct cxl_ras_capability_regs) > len) {
+ pr_err_ratelimited(FW_WARN
+ "CXL CPER prot err DVSEC (%u) overruns section (%u)\n",
+ prot_err->dvsec_len, len);
+ return -EINVAL;
+ }
+
if ((prot_err->agent_type == RCD || prot_err->agent_type == DEVICE ||
prot_err->agent_type == LD || prot_err->agent_type == FMLD) &&
!(prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER))
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index be496bc0386f..7acf209061ea 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -88,7 +88,7 @@ void ghes_estatus_pool_region_free(unsigned long addr, u32 size);
struct cxl_cper_sec_prot_err;
void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
- int severity);
+ int severity, u32 len);
#else
static inline struct list_head *ghes_get_devices(void) { return NULL; }
diff --git a/include/cxl/event.h b/include/cxl/event.h
index b5673384d930..5779e35310c7 100644
--- a/include/cxl/event.h
+++ b/include/cxl/event.h
@@ -312,13 +312,13 @@ static inline int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data
#endif
#ifdef CONFIG_ACPI_APEI_PCIEAER
-int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err);
+int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err, u32 len);
int cxl_cper_setup_prot_err_work_data(struct cxl_cper_prot_err_work_data *wd,
struct cxl_cper_sec_prot_err *prot_err,
int severity);
#else
static inline int
-cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
+cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err, u32 len)
{
return -EOPNOTSUPP;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 10/13] efi/cper: Read only validated fields in cper_mem_err_pack()
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (8 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 09/13] ACPI: APEI: GHES: Validate CXL protocol error section length before RAS cap copy Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 18:09 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 11/13] ACPI: APEI: GHES: Validate memory error section length before payload access Dave Jiang
` (3 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot
cper_mem_err_pack() copies extended, rank, mem_array_handle and
mem_dev_handle unconditionally. Those live at offsets 73 to 79, past the
end of struct cper_sec_mem_err_old, the 73-byte UEFI 2.1/2.2 layout that
older firmware still emits and that cper_estatus_print_section() admits.
On such a record the copy reads up to seven bytes past the payload, and off
the end of the error status block when that section is the last one.
Copy each of the four only when its validation bit is set, and zero it
otherwise. Nothing is lost: a 2.1/2.2 record leaves those bits clear, and
every consumer of struct cper_mem_err_compact already gates the fields on
the same bits. Zeroing also stops callers reading them back out of the
uninitialised on-stack struct they pass in.
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=7
Fixes: 2dfb7d51a61d ("trace, RAS: Add eMCA trace event interface")
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/firmware/efi/cper.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 3dcef618ad39..13b3e72c3b62 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -389,10 +389,28 @@ void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
cmem->requestor_id = mem->requestor_id;
cmem->responder_id = mem->responder_id;
cmem->target_id = mem->target_id;
- cmem->extended = mem->extended;
- cmem->rank = mem->rank;
- cmem->mem_array_handle = mem->mem_array_handle;
- cmem->mem_dev_handle = mem->mem_dev_handle;
+
+ /*
+ * These four sit past the end of the UEFI 2.1/2.2 layout, which older
+ * firmware still emits, so reading them unconditionally runs off a
+ * short record. Every consumer of the compact record gates them on the
+ * same validation bits, so leave them zero when firmware does not
+ * claim them.
+ */
+ cmem->extended = 0;
+ cmem->rank = 0;
+ cmem->mem_array_handle = 0;
+ cmem->mem_dev_handle = 0;
+
+ if (mem->validation_bits &
+ (CPER_MEM_VALID_ROW_EXT | CPER_MEM_VALID_CHIP_ID))
+ cmem->extended = mem->extended;
+ if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
+ cmem->rank = mem->rank;
+ if (mem->validation_bits & CPER_MEM_VALID_CARD_HANDLE)
+ cmem->mem_array_handle = mem->mem_array_handle;
+ if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE)
+ cmem->mem_dev_handle = mem->mem_dev_handle;
}
EXPORT_SYMBOL_GPL(cper_mem_err_pack);
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 11/13] ACPI: APEI: GHES: Validate memory error section length before payload access
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (9 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 10/13] efi/cper: Read only validated fields in cper_mem_err_pack() Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 18:12 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 12/13] ACPI: APEI: GHES: Bound AER info copy and sanitize software metadata Dave Jiang
` (2 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot
ghes_do_proc() hands the CPER_SEC_PLATFORM_MEM payload to the report chain,
arch_apei_report_mem_error() and ghes_handle_memory_failure() without
checking gdata->error_data_length. All three read validation_bits and
physical_addr, at offsets 0 and 16, so a shorter section reads past the
record.
Check the length once in ghes_do_proc(), before any consumer runs. Take the
73-byte struct cper_sec_mem_err_old as the floor: older firmware
legitimately emits that UEFI 2.1/2.2 layout, and it makes validation_bits
safe to read.
The fields from "extended" on are absent from that layout, so also require
whatever length the validation bits claim. Derive it per field rather than
demanding the full 80 bytes: rank needs only 76, and the BANK_GROUP and
BANK_ADDRESS bits describe "bank" at offset 38, which every record carries.
Testing the whole mask against one size, as cper_print_mem() does, gets it
wrong both ways.
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=7
Fixes: ca104edc1784 ("ACPI, APEI, GHES: Cleanup ghes memory error handling")
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/acpi/apei/ghes.c | 41 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 111895c57c2f..2077cc90569a 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -929,6 +929,28 @@ static void ghes_log_hwerr(int sev, guid_t *sec_type)
hwerr_log_error_type(HWERR_RECOV_OTHERS);
}
+/*
+ * The fields from "extended" on are absent from the 73-byte UEFI 2.1/2.2
+ * layout that older firmware still emits. Return the length needed for the
+ * fields the validation bits claim, so over-claiming is rejected without
+ * rejecting an honest short record.
+ */
+static u32 ghes_mem_err_min_len(u64 validation_bits)
+{
+ u32 len = sizeof(struct cper_sec_mem_err_old);
+
+ if (validation_bits & (CPER_MEM_VALID_ROW_EXT | CPER_MEM_VALID_CHIP_ID))
+ len = offsetof(struct cper_sec_mem_err, rank);
+ if (validation_bits & CPER_MEM_VALID_RANK_NUMBER)
+ len = offsetof(struct cper_sec_mem_err, mem_array_handle);
+ if (validation_bits & CPER_MEM_VALID_CARD_HANDLE)
+ len = offsetof(struct cper_sec_mem_err, mem_dev_handle);
+ if (validation_bits & CPER_MEM_VALID_MODULE_HANDLE)
+ len = sizeof(struct cper_sec_mem_err);
+
+ return len;
+}
+
static void ghes_do_proc(struct ghes *ghes,
const struct acpi_hest_generic_status *estatus)
{
@@ -954,6 +976,25 @@ static void ghes_do_proc(struct ghes *ghes,
if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
+ /*
+ * Check once for all three consumers below. The 73-byte
+ * UEFI 2.1/2.2 layout is the floor, matching
+ * cper_estatus_print_section() and making
+ * validation_bits safe to read.
+ */
+ if (gdata->error_data_length <
+ sizeof(struct cper_sec_mem_err_old))
+ continue;
+
+ /* Then require what the claimed fields actually need. */
+ if (gdata->error_data_length <
+ ghes_mem_err_min_len(mem_err->validation_bits)) {
+ pr_warn_ratelimited(FW_WARN GHES_PFX
+ "memory error section too small (%u) for the fields it claims\n",
+ gdata->error_data_length);
+ continue;
+ }
+
atomic_notifier_call_chain(&ghes_report_chain, sev, mem_err);
arch_apei_report_mem_error(sev, mem_err);
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 12/13] ACPI: APEI: GHES: Bound AER info copy and sanitize software metadata
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (10 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 11/13] ACPI: APEI: GHES: Validate memory error section length before payload access Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 18:08 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 13/13] cxl/ras: Make cxl_cper_handle_prot_err() static Dave Jiang
2026-09-04 18:21 ` [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Rafael J. Wysocki (Intel)
13 siblings, 1 reply; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield, sashiko-bot
ghes_handle_aer() copies sizeof(struct aer_capability_regs) out of the
fixed 96-byte pcie_err->aer_info. The struct is larger, so the copy reads
past the section, and it fills the software-only header_len and flit fields
of the embedded struct pcie_tlp_log from firmware bytes.
pcie_print_tlp_log() uses both to bound a loop over dw[], so a large value
walks past the array. Nothing checks the section can hold a struct
cper_sec_pcie either.
Validate error_data_length, zero the destination, and map aer_info onto the
struct as extlog_print_pcie() does: copy up to the four Header Log DWORDs,
then place the TLP Prefix Log from its own offset. The rest stays zero,
covering header_len and flit.
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=3
Fixes: 7e077e6707b3 ("PCI/ERR: Handle TLP Log in Flit mode")
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
v6:
- Also place the TLP Prefix Log from its own hardware offset rather than
leaving it zero. It is the one field the print path reads that the
shortened copy missed (sashiko).
---
drivers/acpi/apei/ghes.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 2077cc90569a..08c985e729d6 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -642,11 +642,14 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
#ifdef CONFIG_ACPI_APEI_PCIEAER
struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata);
+ if (gdata->error_data_length < sizeof(*pcie_err))
+ return;
+
if (pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID &&
pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) {
+ struct aer_capability_regs *aer_info;
unsigned int devfn;
int aer_severity;
- u8 *aer_info;
devfn = PCI_DEVFN(pcie_err->device_id.device,
pcie_err->device_id.function);
@@ -664,13 +667,25 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
sizeof(struct aer_capability_regs));
if (!aer_info)
return;
- memcpy(aer_info, pcie_err->aer_info, sizeof(struct aer_capability_regs));
+
+ /*
+ * Map aer_info onto the struct as extlog_print_pcie() does:
+ * copy up to the four Header Log DWORDs, then place the TLP
+ * Prefix Log from where the hardware keeps it. The rest stays
+ * zero, so firmware cannot drive the pcie_print_tlp_log() loop
+ * over dw[] out of bounds.
+ */
+ memset(aer_info, 0, sizeof(struct aer_capability_regs));
+ memcpy(aer_info, pcie_err->aer_info,
+ offsetof(struct aer_capability_regs, header_log) +
+ PCIE_STD_NUM_TLP_HEADERLOG * sizeof(u32));
+ memcpy(aer_info->header_log.prefix,
+ pcie_err->aer_info + PCI_ERR_PREFIX_LOG,
+ sizeof(aer_info->header_log.prefix));
aer_recover_queue(pcie_err->device_id.segment,
pcie_err->device_id.bus,
- devfn, aer_severity,
- (struct aer_capability_regs *)
- aer_info);
+ devfn, aer_severity, aer_info);
}
#endif
}
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v6 13/13] cxl/ras: Make cxl_cper_handle_prot_err() static
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (11 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 12/13] ACPI: APEI: GHES: Bound AER info copy and sanitize software metadata Dave Jiang
@ 2026-09-04 17:23 ` Dave Jiang
2026-09-04 18:16 ` sashiko-bot
2026-09-04 18:21 ` [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Rafael J. Wysocki (Intel)
13 siblings, 1 reply; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 17:23 UTC (permalink / raw)
To: linux-acpi, linux-cxl
Cc: rafael, tony.luck, bp, guohanjun, mchehab, xueshuai, terry.bowman,
benjamin.cheatham, alison.schofield
The extlog caller went away when extlog switched to
cxl_cper_post_prot_err(), leaving cxl_cper_prot_err_work_fn() in the same
file as the only caller.
Drop the export and the declaration in <cxl/event.h>, and make it static.
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/cxl/core/ras.c | 3 +--
include/cxl/event.h | 2 --
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
index e307361bb39e..c91db125a971 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -77,7 +77,7 @@ static int match_memdev_by_parent(struct device *dev, const void *uport)
return 0;
}
-void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data)
+static void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data)
{
unsigned int devfn = PCI_DEVFN(data->prot_err.agent_addr.device,
data->prot_err.agent_addr.function);
@@ -118,7 +118,6 @@ void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data)
else
cxl_cper_trace_uncorr_prot_err(cxlmd, data->ras_cap);
}
-EXPORT_SYMBOL_GPL(cxl_cper_handle_prot_err);
static void cxl_cper_prot_err_work_fn(struct work_struct *work)
{
diff --git a/include/cxl/event.h b/include/cxl/event.h
index 5779e35310c7..a9f5c2381cc9 100644
--- a/include/cxl/event.h
+++ b/include/cxl/event.h
@@ -331,6 +331,4 @@ cxl_cper_setup_prot_err_work_data(struct cxl_cper_prot_err_work_data *wd,
}
#endif
-void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *wd);
-
#endif /* _LINUX_CXL_EVENT_H */
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v6 02/13] efi/cper: Reject an error status block length that wraps a u32
2026-09-04 17:23 ` [PATCH v6 02/13] efi/cper: Reject an error status block length that wraps a u32 Dave Jiang
@ 2026-09-04 17:38 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-09-04 17:38 UTC (permalink / raw)
To: Dave Jiang; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Out-of-bounds read in CPER error status validation due to insufficient remaining length check
--
commit 397f02447210fe6eca20cec521b708fca415a921
Author: Dave Jiang <dave.jiang@intel.com>
efi/cper: Reject an error status block length that wraps a u32
cper_estatus_len() sums the firmware-controlled data_length into a u32,
which can wrap to 0. This patch rejects a length that cannot be expressed in
a u32 in cper_estatus_check_header() to prevent callers from receiving a
short value.
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=1
> diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
> index 332c78f2d5617..3dcef618ad39f 100644
> --- a/drivers/firmware/efi/cper.c
> +++ b/drivers/firmware/efi/cper.c
> @@ -745,6 +745,17 @@ int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus)
> estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
> return -EINVAL;
>
> + /*
> + * cper_estatus_len() sums these into a u32, and a wrapped sum reads
> + * back smaller than the record. Reject a length that cannot be
> + * expressed so no caller is handed the short value.
> + */
> + if ((u64)sizeof(*estatus) + estatus->data_length > U32_MAX)
> + return -EINVAL;
> + if (estatus->raw_data_length &&
> + (u64)estatus->raw_data_offset + estatus->raw_data_length > U32_MAX)
> + return -EINVAL;
> +
> return 0;
> }
> EXPORT_SYMBOL_GPL(cper_estatus_check_header);
[Severity: High]
This isn't a bug introduced by this patch, but while looking at validation
for estatus->data_length here, I noticed an out-of-bounds read issue in how
the sections are parsed by cper_estatus_check().
If firmware provides an estatus block where the data_length leaves between 1
and 63 bytes (smaller than sizeof(struct acpi_hest_generic_data)) after a
valid section, the apei_estatus_for_each_section() loop will erroneously
enter another iteration due to its boundary condition:
include/acpi/ghes.h:apei_estatus_for_each_section()
for (section = (struct acpi_hest_generic_data *)(estatus + 1); \
(void *)section - (void *)(estatus + 1) < estatus->data_length; \
section = acpi_hest_get_next(section))
The subsequent access to acpi_hest_get_size(gdata) and
gdata->error_data_length in cper_estatus_check() will then read past the
valid data_length.
drivers/firmware/efi/cper.c:cper_estatus_check()
apei_estatus_for_each_section(estatus, gdata) {
int record_size;
if (check_add_overflow(acpi_hest_get_size(gdata),
gdata->error_data_length, &record_size))
return -EINVAL;
A heap out-of-bounds read here can cause a page fault in MCE or NMI context,
leading to a fatal machine check (kernel panic).
Could we tighten the apei_estatus_for_each_section loop boundary or add a
check in cper_estatus_check() to ensure the remaining data_length is at
least the size of a section header before allowing the next iteration?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang@intel.com?part=2
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v6 01/13] efi/cper: Reject CPER records with an out-of-range error_data_length
2026-09-04 17:23 ` [PATCH v6 01/13] efi/cper: Reject CPER records with an out-of-range error_data_length Dave Jiang
@ 2026-09-04 17:39 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-09-04 17:39 UTC (permalink / raw)
To: Dave Jiang; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] The section iterator allows out-of-bounds memory reads when evaluating the generic data header on truncated CPER records.
--
commit 11208300cad76f5a8ea35d8ac53a2941f6447499
Author: Dave Jiang <dave.jiang@intel.com>
efi/cper: Reject CPER records with an out-of-range error_data_length
This commit uses check_add_overflow() to reject CPER records with a huge
error_data_length that wraps around when summed with the header size. It
prevents infinite loops or out-of-bounds walks caused by integer overflow
during section iteration.
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=1
> diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
> index 06b4fdb59917a..332c78f2d5617 100644
> --- a/drivers/firmware/efi/cper.c
> +++ b/drivers/firmware/efi/cper.c
[ ... ]
> @@ -762,10 +762,18 @@ int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
> data_len = estatus->data_length;
>
> apei_estatus_for_each_section(estatus, gdata) {
> - if (acpi_hest_get_size(gdata) > data_len)
> + int record_size;
> +
> + /*
> + * The <acpi/ghes.h> helpers sum these as a signed int, so a
> + * huge error_data_length wraps small rather than large and the
> + * walk then advances by that wrapped value. Reject a size an
> + * int cannot carry.
> + */
> + if (check_add_overflow(acpi_hest_get_size(gdata),
> + gdata->error_data_length, &record_size))
[Severity: High]
This isn't a bug introduced by this patch, but does the section iterator
allow out-of-bounds memory reads when evaluating the generic data header on
truncated CPER records?
If the firmware provides a CPER record where the total data length covers
the first section plus a small positive remainder (for example, 1 byte), the
apei_estatus_for_each_section() loop will advance to the second section
because there is still remaining data length.
Inside the loop, the updated code evaluates check_add_overflow():
if (check_add_overflow(acpi_hest_get_size(gdata),
gdata->error_data_length, &record_size))
This evaluates acpi_hest_get_size(gdata) (which accesses gdata->revision)
and reads gdata->error_data_length before verifying that the remaining data
length is large enough to contain the generic data header.
Could this trigger a page fault and kernel panic in NMI or IRQ context if
the firmware error logs are malformed? While this problem was pre-existing,
this patch replaces the acpi_hest_get_size() check with check_add_overflow(),
adding an unconditional read of gdata->error_data_length to the existing
out-of-bounds read of gdata->revision.
> return -EINVAL;
>
> - record_size = acpi_hest_get_record_size(gdata);
> if (record_size > data_len)
> return -EINVAL;
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang@intel.com?part=1
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v6 03/13] ACPI: extlog: Validate elog record length before walking sections
2026-09-04 17:23 ` [PATCH v6 03/13] ACPI: extlog: Validate elog record length before walking sections Dave Jiang
@ 2026-09-04 17:40 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-09-04 17:40 UTC (permalink / raw)
To: Dave Jiang; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing bounds check on firmware-supplied physical address allows out-of-bounds memory read (and potential kernel panic) when mapped to a virtual address.
--
commit 7d4af53bdefb9af34e8feff4c7e1e31654f51d71
Author: Dave Jiang <dave.jiang@intel.com>
Subject: ACPI: extlog: Validate elog record length before walking sections
This patch adds validation to extlog_print() to bound the length of elog
records and check them via cper_estatus_check() before walking the sections.
It drops malformed records to prevent out-of-bounds reads if data_length
extends past elog_buf.
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=6
> diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
> index 7ad3b36013cc6..046e92ee195f9 100644
> --- a/drivers/acpi/acpi_extlog.c
> +++ b/drivers/acpi/acpi_extlog.c
> @@ -208,6 +208,15 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
>
> tmp = (struct acpi_hest_generic_status *)elog_buf;
>
> + /*
> + * Bound the length before cper_estatus_check() walks the sections: it
> + * iterates over data_length, which is not yet known to fit elog_buf.
> + * cper_estatus_check_header() then rejects a length that wrapped, which
> + * the bound cannot see.
> + */
> + if (cper_estatus_len(tmp) > ELOG_ENTRY_LEN || cper_estatus_check(tmp))
> + return NOTIFY_DONE;
> +
[Severity: High]
This is a pre-existing issue, but since the goal of this code is to protect
against malformed firmware records, there appears to be a missing bounds
check earlier in this path.
In drivers/acpi/acpi_extlog.c:extlog_elog_entry_check():
data = ELOG_ENTRY_DATA(idx);
if ((data & ELOG_ENTRY_VALID) == 0)
return NULL;
data &= EXT_ELOG_ENTRY_MASK;
estatus = (struct acpi_hest_generic_status *)ELOG_ENTRY_ADDR(data);
/* if no valid data in elog entry, just return */
if (estatus->block_status == 0)
return NULL;
The physical address read from the firmware-controlled L1 directory into
data is converted to a virtual pointer via the ELOG_ENTRY_ADDR() macro. It
is then immediately dereferenced by estatus->block_status.
Is there anything verifying that this physical address falls within the
mapped elog_base to elog_base + elog_size boundaries?
If the resulting virtual address points to an unmapped page in the vmalloc
or ioremap region, could this dereference cause a kernel page fault and
panic?
> if (!ras_userspace_consumers()) {
> print_extlog_rcd(NULL, tmp, cpu);
> goto out;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang@intel.com?part=3
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v6 05/13] ACPI: extlog: Avoid populating software AER metadata from raw hardware buffer
2026-09-04 17:23 ` [PATCH v6 05/13] ACPI: extlog: Avoid populating software AER metadata from raw hardware buffer Dave Jiang
@ 2026-09-04 17:58 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-09-04 17:58 UTC (permalink / raw)
To: Dave Jiang; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The patch truncates Flit mode TLP logs by strictly copying only 16 bytes of the prefix log and deliberately leaving `flit` and `header_len` as zero.
--
commit a79ba2cb1ba02ad8827d582fce99b0fe70c8796e
Author: Dave Jiang <dave.jiang@intel.com>
ACPI: extlog: Avoid populating software AER metadata from raw hardware buffer
This commit fixes an issue in extlog_print_pcie() where casting the hardware
aer_info buffer directly to struct aer_capability_regs could fill software-only
metadata fields (header_len and flit) with raw firmware bytes. It introduces a
safer local copy mechanism to populate only the hardware-backed fields while
keeping the rest zeroed.
Closes: https://lore.kernel.org/linux-cxl/20260709165457.8BA181F000E9@smtp.kernel.org/
> diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
> index 2451362e696dc..1b61788abd5a6 100644
> --- a/drivers/acpi/acpi_extlog.c
> +++ b/drivers/acpi/acpi_extlog.c
> @@ -149,7 +149,21 @@ 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;
> +
> + /*
> + * struct pcie_tlp_log is larger than the hardware layout, so aer_info
> + * only maps onto the struct up to the four Header Log DWORDs. Copy that
> + * much, then place the TLP Prefix Log from where the hardware keeps it.
> + * Everything else stays zero: nothing reads root_command, root_status or
> + * the error source IDs, and header_len and flit are software-only.
> + */
> + memcpy(&aer_regs, pcie_err->aer_info,
> + offsetof(struct aer_capability_regs, header_log) +
> + PCIE_STD_NUM_TLP_HEADERLOG * sizeof(u32));
> + memcpy(aer_regs.header_log.prefix,
> + pcie_err->aer_info + PCI_ERR_PREFIX_LOG,
> + sizeof(aer_regs.header_log.prefix));
[Severity: Medium]
Does this strict 16-byte copy truncate the TLP Prefix Log in Flit mode?
By hardcoding sizeof(aer_regs.header_log.prefix) (16 bytes) and deliberately
leaving the software metadata fields 'flit' and 'header_len' as zero, this
appears to drop up to 24 bytes (6 DWORDs) of the Flit mode extended TLP header
from the hardware buffer.
If a PCIe error occurs in Flit mode, the error would be printed as if it were a
non-Flit mode error, leading to incomplete diagnostic information in dmesg.
Should this logic account for Flit mode to ensure the entire extended header
data is accurately copied?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang@intel.com?part=5
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v6 09/13] ACPI: APEI: GHES: Validate CXL protocol error section length before RAS cap copy
2026-09-04 17:23 ` [PATCH v6 09/13] ACPI: APEI: GHES: Validate CXL protocol error section length before RAS cap copy Dave Jiang
@ 2026-09-04 18:05 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-09-04 18:05 UTC (permalink / raw)
To: Dave Jiang; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] Out-of-Bounds Read in `cxl_cper_print_prot_err` when dumping firmware-controlled length
- [High] Mismatched validation check in `cxl_cper_sec_prot_err_valid` drops valid errors and accepts uninitialized agent types
- [High] Invalid pointer comparison in `match_memdev_by_parent` entirely breaks CPER log association for memdevs
--
commit 370881a728ea6e57fe2c8f02a8283fec779e22bb
Author: Dave Jiang <dave.jiang@intel.com>
ACPI: APEI: GHES: Validate CXL protocol error section length before RAS cap copy
This commit extends cxl_cper_sec_prot_err_valid() to check the section length
before copying the RAS Capability block. It ensures the header, DVSEC, and RAS
Capability block fit within the reported length to prevent out-of-bounds access.
Link: https://sashiko.dev/#/patchset/20260617-topics-ahmtib01-ras_ffh_arm_internal_review-v6-0-91f725174aa0@arm.com?part=6
Link: https://lore.kernel.org/linux-cxl/20260709165457.8BA181F000E9@smtp.kernel.org/
> diff --git a/drivers/acpi/apei/ghes_helpers.c b/drivers/acpi/apei/ghes_helpers.c
> index bc7111b740afb..df41b993f4130 100644
> --- a/drivers/acpi/apei/ghes_helpers.c
> +++ b/drivers/acpi/apei/ghes_helpers.c
> @@ -5,8 +5,15 @@
> #include <linux/aer.h>
> #include <cxl/event.h>
>
> -int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
> +int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err, u32 len)
> {
> + if (len < sizeof(*prot_err)) {
> + pr_err_ratelimited(FW_WARN
> + "CXL CPER prot err section too small (%u)\n",
> + len);
> + return -EINVAL;
> + }
> +
> if (!(prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS)) {
> pr_err_ratelimited("CXL CPER invalid agent type\n");
> return -EINVAL;
> }
[Severity: High]
This is a pre-existing issue, but does this check use the wrong validation bit?
It checks for PROT_ERR_VALID_AGENT_ADDRESS, but the error message states
"invalid agent type", which suggests it should be checking for
PROT_ERR_VALID_AGENT_TYPE.
If the firmware provides a CPER record lacking PROT_ERR_VALID_AGENT_ADDRESS,
valid hardware errors might be silently dropped. If it lacks
PROT_ERR_VALID_AGENT_TYPE, could uninitialized garbage be processed as the
agent type?
While reviewing this patch, I also noticed a pre-existing issue in related
printing code:
drivers/firmware/efi/cper_cxl.c:cxl_cper_print_prot_err() {
...
print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, (prot_err + 1),
prot_err->dvsec_len, 0);
...
size_t size = sizeof(*prot_err) + prot_err->dvsec_len;
struct cxl_ras_capability_regs *cxl_ras;
...
cxl_ras = (struct cxl_ras_capability_regs *)((long)prot_err + size);
pr_info("%s cxl_ras_uncor_status: 0x%08x", pfx,
cxl_ras->uncor_status);
}
[Severity: High]
This is a pre-existing issue, but could this cause an out-of-bounds read?
The exact same vulnerability fixed by this patch in
cxl_cper_setup_prot_err_work_data() seems to exist here. The callers in
cper.c do not pass the bounding length to cxl_cper_print_prot_err(), so it uses
prot_err->dvsec_len unvalidated for print_hex_dump() and to calculate the
pointer to cxl_ras.
If firmware provides an artificially large dvsec_len, could this read
out-of-bounds kernel memory into dmesg or cause a panic?
I also noticed another pre-existing issue in the error handling path:
drivers/cxl/core/ras.c:match_memdev_by_parent() {
if (is_cxl_memdev(dev) && dev->parent == uport)
return 1;
}
... called from:
drivers/cxl/core/ras.c:cxl_cper_handle_prot_err() {
...
struct device *mem_dev __free(put_device) = bus_find_device(
&cxl_bus_type, NULL, pdev, match_memdev_by_parent);
...
}
[Severity: High]
This is a pre-existing issue, but will this search always fail?
In cxl_cper_handle_prot_err(), pdev (a struct pci_dev *) is passed as the match
data (uport). The match_memdev_by_parent() function compares dev->parent (a
struct device *) directly to uport (a struct pci_dev *).
Since struct device is embedded within struct pci_dev at a non-zero offset,
dev->parent will never equal pdev. Could this entirely break CPER log
association for memdevs?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang@intel.com?part=9
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v6 12/13] ACPI: APEI: GHES: Bound AER info copy and sanitize software metadata
2026-09-04 17:23 ` [PATCH v6 12/13] ACPI: APEI: GHES: Bound AER info copy and sanitize software metadata Dave Jiang
@ 2026-09-04 18:08 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-09-04 18:08 UTC (permalink / raw)
To: Dave Jiang; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Memory leak of `aer_capability_regs` allocated from `ghes_estatus_pool` in error paths of `aer_recover_queue` and `aer_recover_work_func`.
--
commit 639b51ace1216953e300ae9efcce13516dadf849
Author: Dave Jiang <dave.jiang@intel.com>
ACPI: APEI: GHES: Bound AER info copy and sanitize software metadata
This commit validates the error_data_length in ghes_handle_aer() and ensures
that copying firmware error information into the larger aer_capability_regs
struct does not read out of bounds. It also zeroes out the destination and
properly maps the header log and prefix log to prevent firmware from
manipulating software-only fields.
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=3
Fixes: 7e077e6707b3 ("PCI/ERR: Handle TLP Log in Flit mode")
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 2077cc90569a0..08c985e729d6c 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
[ ... ]
> @@ -664,13 +667,25 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
> sizeof(struct aer_capability_regs));
> if (!aer_info)
> return;
> - memcpy(aer_info, pcie_err->aer_info, sizeof(struct aer_capability_regs));
> +
> + /*
> + * Map aer_info onto the struct as extlog_print_pcie() does:
> + * copy up to the four Header Log DWORDs, then place the TLP
> + * Prefix Log from where the hardware keeps it. The rest stays
> + * zero, so firmware cannot drive the pcie_print_tlp_log() loop
> + * over dw[] out of bounds.
> + */
> + memset(aer_info, 0, sizeof(struct aer_capability_regs));
> + memcpy(aer_info, pcie_err->aer_info,
> + offsetof(struct aer_capability_regs, header_log) +
> + PCIE_STD_NUM_TLP_HEADERLOG * sizeof(u32));
> + memcpy(aer_info->header_log.prefix,
> + pcie_err->aer_info + PCI_ERR_PREFIX_LOG,
> + sizeof(aer_info->header_log.prefix));
>
> aer_recover_queue(pcie_err->device_id.segment,
> pcie_err->device_id.bus,
> - devfn, aer_severity,
> - (struct aer_capability_regs *)
> - aer_info);
> + devfn, aer_severity, aer_info);
[Severity: High]
This is a pre-existing issue, but does this code leak the newly allocated
aer_info pointer from ghes_estatus_pool if the recovery queue is full or if
the device is not found during workqueue execution?
The memory is allocated from the fixed-size pool earlier in ghes_handle_aer():
drivers/acpi/apei/ghes.c:ghes_handle_aer() {
...
aer_info = (void *)gen_pool_alloc(ghes_estatus_pool,
sizeof(struct aer_capability_regs));
...
}
However, in drivers/pci/pcie/aer.c:aer_recover_queue(), if the internal kfifo
is full, the pointer is dropped without being freed:
drivers/pci/pcie/aer.c:aer_recover_queue() {
...
if (kfifo_in_spinlocked(&aer_recover_ring, &entry, 1,
&aer_recover_ring_lock))
schedule_work(&aer_recover_work);
else
pr_err("buffer overflow in recovery for %04x:%02x:%02x.%x\n",
domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
...
}
Additionally, in drivers/pci/pcie/aer.c:aer_recover_work_func(), if the target
PCI device cannot be found (for instance, due to hot-removal), the function
bypasses the pool region free:
drivers/pci/pcie/aer.c:aer_recover_work_func() {
...
if (!pdev) {
pr_err_ratelimited("%04x:%02x:%02x.%x: no pci_dev found\n",
entry.domain, entry.bus,
PCI_SLOT(entry.devfn),
PCI_FUNC(entry.devfn));
continue;
}
...
}
The continue statement bypasses the subsequent call to
ghes_estatus_pool_region_free(), which leaks the entry.regs pointer. Can this
eventually exhaust the fixed-size ghes_estatus_pool during error storms and
cause subsequent hardware error reports to be silently dropped?
> }
> #endif
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang@intel.com?part=12
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v6 10/13] efi/cper: Read only validated fields in cper_mem_err_pack()
2026-09-04 17:23 ` [PATCH v6 10/13] efi/cper: Read only validated fields in cper_mem_err_pack() Dave Jiang
@ 2026-09-04 18:09 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-09-04 18:09 UTC (permalink / raw)
To: Dave Jiang; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing minimum length validation for error section payloads in `cper_print_mem()` leading to out-of-bounds memory reads if firmware provides a heavily truncated record.
- [High] acpi_extlog silently drops valid UEFI 2.1/2.2 73-byte records.
--
commit de79ea2e5b5e1256b6281744b6c0756366762e76
Author: Dave Jiang <dave.jiang@intel.com>
efi/cper: Read only validated fields in cper_mem_err_pack()
This patch modifies cper_mem_err_pack() to conditionally copy extended, rank,
mem_array_handle, and mem_dev_handle fields based on their validation bits,
preventing out-of-bounds reads when processing 73-byte UEFI 2.1/2.2 records.
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=7
> diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
> index 3dcef618ad39f..13b3e72c3b62f 100644
> --- a/drivers/firmware/efi/cper.c
> +++ b/drivers/firmware/efi/cper.c
[ ... ]
> @@ -389,10 +389,28 @@ void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
> cmem->requestor_id = mem->requestor_id;
> cmem->responder_id = mem->responder_id;
> cmem->target_id = mem->target_id;
> - cmem->extended = mem->extended;
> - cmem->rank = mem->rank;
> - cmem->mem_array_handle = mem->mem_array_handle;
> - cmem->mem_dev_handle = mem->mem_dev_handle;
> +
> + /*
> + * These four sit past the end of the UEFI 2.1/2.2 layout, which older
> + * firmware still emits, so reading them unconditionally runs off a
> + * short record. Every consumer of the compact record gates them on the
> + * same validation bits, so leave them zero when firmware does not
> + * claim them.
> + */
> + cmem->extended = 0;
> + cmem->rank = 0;
> + cmem->mem_array_handle = 0;
> + cmem->mem_dev_handle = 0;
> +
> + if (mem->validation_bits &
> + (CPER_MEM_VALID_ROW_EXT | CPER_MEM_VALID_CHIP_ID))
> + cmem->extended = mem->extended;
> + if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
> + cmem->rank = mem->rank;
> + if (mem->validation_bits & CPER_MEM_VALID_CARD_HANDLE)
> + cmem->mem_array_handle = mem->mem_array_handle;
> + if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE)
> + cmem->mem_dev_handle = mem->mem_dev_handle;
[Severity: High]
This isn't a bug introduced by this patch, but does this code still perform
out-of-bounds reads if the firmware provides a heavily truncated record?
In cper_print_mem(), if the error data length is between 74 and 79 bytes,
the exact-match length check is bypassed:
if (len == sizeof(struct cper_sec_mem_err_old) &&
(mem->validation_bits & ~(CPER_MEM_VALID_RANK_NUMBER - 1))) {
pr_err(FW_WARN "valid bits set for fields beyond structure\n");
return;
}
Then, cper_print_mem() calls cper_mem_err_pack() which evaluates the
validation bits without verifying if the length is large enough to cover the
claimed fields. If firmware provides a short record (e.g., 74 bytes) and sets
CPER_MEM_VALID_MODULE_HANDLE, wouldn't we still read out-of-bounds from the
estatus buffer here?
Note that a later patch in this series (commit "ACPI: APEI: GHES: Validate
memory error section length before payload access") fixes this issue in
ghes_do_proc(), but the caller path through cper_estatus_print_section() to
cper_print_mem() appears to miss this length validation.
> }
> EXPORT_SYMBOL_GPL(cper_mem_err_pack);
[Severity: High]
This is a pre-existing issue, but since this patch series addresses legacy
73-byte records, does the size check in extlog_print() silently drop valid
UEFI 2.1/2.2 records?
drivers/acpi/acpi_extlog.c:extlog_print() {
...
if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
struct cper_sec_mem_err *mem = acpi_hest_get_payload(gdata);
if (gdata->error_data_length >= sizeof(*mem))
trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
(u8)gdata->error_severity);
...
}
Since sizeof(*mem) evaluates to 80 bytes (the size of the newer struct),
wouldn't this check silently reject 73-byte records and prevent them from
being traced?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang@intel.com?part=10
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v6 11/13] ACPI: APEI: GHES: Validate memory error section length before payload access
2026-09-04 17:23 ` [PATCH v6 11/13] ACPI: APEI: GHES: Validate memory error section length before payload access Dave Jiang
@ 2026-09-04 18:12 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-09-04 18:12 UTC (permalink / raw)
To: Dave Jiang; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] The patch fixes length validation in ghes_do_proc() but leaves an identical logic flaw and buffer over-read unfixed in cper_print_mem().
--
commit 8bbaca1beceadb4f3349da69c4f0bedd1d913c54
Author: Dave Jiang <dave.jiang@intel.com>
Subject: ACPI: APEI: GHES: Validate memory error section length before payload access
This patch adds length validation in ghes_do_proc() before accessing the
CPER_SEC_PLATFORM_MEM payload to prevent reading past the record. It ensures
records are at least 73 bytes and validates the remaining length based on the
claimed fields.
Closes: https://sashiko.dev/#/patchset/20260714231835.303081-1-dave.jiang@intel.com?part=7
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 111895c57c2f9..2077cc90569a0 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
[ ... ]
> @@ -954,6 +976,25 @@ static void ghes_do_proc(struct ghes *ghes,
> if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
> struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
>
> + /*
> + * Check once for all three consumers below. The 73-byte
> + * UEFI 2.1/2.2 layout is the floor, matching
> + * cper_estatus_print_section() and making
> + * validation_bits safe to read.
> + */
> + if (gdata->error_data_length <
> + sizeof(struct cper_sec_mem_err_old))
> + continue;
> +
[Severity: High]
This isn't a bug introduced by this patch, but does leaving cper_print_mem()
unfixed bypass these newly added safety checks?
As noted in the commit message, cper_print_mem() gets the mask checking
wrong. When firmware provides a CPER memory error record with a length
between 74 and 79 bytes, the exact match check in cper_print_mem() fails to
catch the invalid length:
drivers/firmware/efi/cper.c:cper_print_mem() {
...
/* Don't trust UEFI 2.1/2.2 structure with bad validation bits */
if (len == sizeof(struct cper_sec_mem_err_old) &&
(mem->validation_bits & ~(CPER_MEM_VALID_RANK_NUMBER - 1))) {
pr_err(FW_WARN "valid bits set for fields beyond structure\n");
return;
}
...
}
Because ghes_proc() calls ghes_print_estatus() before ghes_do_proc(), this
code executes before the new checks in this patch are reached.
When cper_print_mem() then calls cper_mem_err_pack(), it blindly reads
out-of-bounds fields if the payload is smaller than 80 bytes:
drivers/firmware/efi/cper.c:cper_mem_err_pack() {
...
if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE)
cmem->mem_dev_handle = mem->mem_dev_handle;
...
}
Could this result in an out-of-bounds memory read (such as mem_dev_handle
at offset 78) and an information leak to dmesg before ghes_do_proc() has a
chance to reject the malformed record?
> + /* Then require what the claimed fields actually need. */
> + if (gdata->error_data_length <
> + ghes_mem_err_min_len(mem_err->validation_bits)) {
> + pr_warn_ratelimited(FW_WARN GHES_PFX
> + "memory error section too small (%u) for the fields it claims\n",
> + gdata->error_data_length);
> + continue;
> + }
> +
> atomic_notifier_call_chain(&ghes_report_chain, sev, mem_err);
>
> arch_apei_report_mem_error(sev, mem_err);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang@intel.com?part=11
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v6 13/13] cxl/ras: Make cxl_cper_handle_prot_err() static
2026-09-04 17:23 ` [PATCH v6 13/13] cxl/ras: Make cxl_cper_handle_prot_err() static Dave Jiang
@ 2026-09-04 18:16 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-09-04 18:16 UTC (permalink / raw)
To: Dave Jiang; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] bus_find_device() is passed a struct pci_dev pointer instead of a struct device pointer, causing the match function to always fail and skipping CXL CPER endpoint error tracing.
--
commit 8c6686bf6f4e6de777942d8a16f6142155da2ee3
Author: Dave Jiang <dave.jiang@intel.com>
cxl/ras: Make cxl_cper_handle_prot_err() static
The extlog caller went away when extlog switched to
cxl_cper_post_prot_err(), leaving cxl_cper_prot_err_work_fn() in the same
file as the only caller. Drop the export and the declaration in
<cxl/event.h>, and make it static.
> diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
> index e307361bb39e4..c91db125a9714 100644
> --- a/drivers/cxl/core/ras.c
> +++ b/drivers/cxl/core/ras.c
> @@ -77,7 +77,7 @@ static int match_memdev_by_parent(struct device *dev, const void *uport)
> return 0;
> }
>
> -void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data)
> +static void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data)
[Severity: High]
This is a pre-existing issue, but I noticed a bug in how this function
searches for the memdev using bus_find_device().
Does this code always fail to match the memdev, skipping the CXL CPER
endpoint error tracing entirely?
Inside cxl_cper_handle_prot_err(), bus_find_device() is called with pdev
(a struct pci_dev pointer) as the search context:
drivers/cxl/core/ras.c:cxl_cper_handle_prot_err() {
...
struct device *mem_dev __free(put_device) = bus_find_device(
&cxl_bus_type, NULL, pdev, match_memdev_by_parent);
...
}
However, match_memdev_by_parent() expects uport to be a pointer to a
struct device in order for the comparison to work:
drivers/cxl/core/ras.c:match_memdev_by_parent() {
if (is_cxl_memdev(dev) && dev->parent == uport)
return 1;
return 0;
}
Because struct device is embedded inside struct pci_dev at a non-zero
offset, dev->parent will never equal the pdev pointer. This guarantees
bus_find_device() will return NULL, causing hardware protocol errors on
CXL memory devices to be silently dropped instead of being traced.
Should bus_find_device() be called with &pdev->dev instead of pdev?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang@intel.com?part=13
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
` (12 preceding siblings ...)
2026-09-04 17:23 ` [PATCH v6 13/13] cxl/ras: Make cxl_cper_handle_prot_err() static Dave Jiang
@ 2026-09-04 18:21 ` Rafael J. Wysocki (Intel)
2026-09-04 19:44 ` Dave Jiang
13 siblings, 1 reply; 25+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-04 18:21 UTC (permalink / raw)
To: Dave Jiang
Cc: linux-acpi, linux-cxl, rafael, tony.luck, bp, guohanjun, mchehab,
xueshuai, terry.bowman, benjamin.cheatham, alison.schofield,
Jonathan Cameron
On Fri, Sep 4, 2026 at 7:23 PM Dave Jiang <dave.jiang@intel.com> wrote:
>
> Fixes for pre-existing issues sashiko-bot found while reviewing patches in the
> CPER, extlog and GHES paths. v1 through v3 fixed successive batches as the
> review widened; see the links below.
>
> The series is grouped in three parts, plus a cleanup.
>
> Bound the record before anything walks it:
>
> 1/13: Reject CPER records with an out-of-range error_data_length.
> 2/13: Reject an error status block length that wraps a u32.
> 3/13: Validate the extlog record length before walking sections.
>
> Fix the extlog error paths, then enable them:
>
> 4/13: Defer CXL protocol error handling to avoid a lock inversion.
> 5/13: Avoid populating software AER metadata from the raw hardware buffer.
> 6/13: Validate the PCIe error section length before payload access.
> 7/13: Fix the CONFIG_ACPI_APEI_PCIEAER guard typo in extlog.c.
>
> Bound each section payload before its consumers read it:
>
> 8/13: Bound the CXL event record copy to the firmware section length.
> 9/13: Validate the CXL protocol error section length before the RAS cap copy.
> 10/13: Read only validated fields in cper_mem_err_pack().
> 11/13: Validate the memory error section length before payload access.
> 12/13: Bound the AER info copy and sanitize software metadata in ghes.c.
>
> Then drop an export patch 4 made redundant:
>
> 13/13: Make cxl_cper_handle_prot_err() static.
>
> Patches 1, 2 and 10 touch drivers/firmware/efi/cper.c, closing the holes at
> the shared choke point the rest of the series relies on. Patch 2 also fixes an
> infinite loop in bert_print_all(), unrelated to this series but the same root
> cause.
>
> Known gaps, left for separate patches:
>
> - cxl_cper_print_prot_err() in drivers/firmware/efi/cper_cxl.c uses
> dvsec_len without bounding it against the section length.
> - cxl_rch_get_aer_info() in drivers/cxl/core/ras_rch.c reads the RCH AER
> capability from MMIO without clearing header_len/flit, the same class as
> patches 5 and 12. In the same file, cxl_rch_get_aer_severity() tests
> PCI_ERR_ROOT_FATAL_RCV against uncor_status, where that bit is
> PCI_ERR_UNC_FCP.
> - struct pcie_tlp_log grew to 60 bytes for Flit mode, so the 96-byte CPER
> AER info no longer maps 1:1 onto struct aer_capability_regs past the
> Header Log. Patches 5 and 12 now copy the part that maps and place the TLP
> Prefix Log from its own offset, which covers every field the print path
> reads - but nothing here decodes the Flit-mode header DWORDs, which reuse
> those same prefix registers at payload offset 56 while the struct expects
> dw[4..13] at 44. Doing that properly wants a field-by-field mapping
> shared with cxl_rch_get_aer_info(), plus a clamp: pcie_print_tlp_log()
> trusts header_len against a 14-entry dw[], and PCI_ERR_CAP_TLP_LOG_SIZE
> is five bits wide.
>
> v1: https://lore.kernel.org/linux-cxl/20260709162807.1957783-1-dave.jiang@intel.com/
> v2: https://lore.kernel.org/linux-cxl/20260714231835.303081-1-dave.jiang@intel.com/
> v3: https://lore.kernel.org/linux-cxl/20260717161647.1493259-1-dave.jiang@intel.com/
> v4: https://lore.kernel.org/linux-cxl/20260824174936.939059-1-dave.jiang@intel.com/
> v5: https://lore.kernel.org/linux-cxl/20260827203726.3027541-1-dave.jiang@intel.com/
>
> Changes since v5
> ----------------
> - Patches 5 and 12: also place the TLP Prefix Log from its own hardware
> offset rather than leaving it zero. Shortening the copy in v5 dropped it,
> and it is the one field the print path still reads (sashiko). Alison's and
> Shuai's Reviewed-by are kept on both, since the intent and location have
> not changed.
>
> Changes since v4
> ----------------
> - Patch 1: use check_add_overflow() instead of a u64 sum plus an INT_MAX
> test, and drop the now-redundant acpi_hest_get_size() bound, since
> record_size is never smaller than the header (Jonathan Cameron).
> - Patches 5 and 12: copy only the 44 bytes of aer_info that map onto struct
> aer_capability_regs - the leading registers and the four Header Log DWORDs
> - and leave the rest zero, instead of copying all 96 bytes and then
> clearing header_len and flit (Jonathan Cameron). That also keeps the Root
> Error Command, Root Error Status and Error Source ID out of
> header_log.prefix[], where pcie_print_tlp_log() was printing them as
> end-to-end prefixes.
> - Patch 3: kept the length bound ahead of cper_estatus_check() and expanded
> the comment to say why. Swapping them would let cper_estatus_check() walk
> sections over an unbounded data_length, past the end of elog_buf
> (Jonathan Cameron).
> - Condensed the commit logs and comments again; prose only.
>
> Changes since v3
> ----------------
> - Regrouped into three parts: bound the record, fix and enable the extlog
> paths, then bound each section payload. v3 interleaved them, so patch 1
> checked a section before the patch establishing that contract. No code
> changed.
> - Moved the extlog lock inversion fix (patch 4) ahead of the CXL protocol
> error length validation (patch 9). The former deletes
> extlog_cxl_cper_handle_prot_err(), which the v3 order plumbed a new len
> argument through three patches before removing it. No functional change.
> - Patch 1: bound the sum rather than the u32 error_data_length, so the check
> does not depend on the <acpi/ghes.h> helpers behaving. The v3 "< 0" check
> was dead code (Tony Luck, Shuai Xue). Reviewed-by dropped; not the same
> check.
> - New patch 2: reject an error status block length that wraps the u32 sum in
> cper_estatus_len(). A data_length of 0xffffffec makes it read back as 0,
> slipping past the extlog bound in patch 3 and leaving bert_print_all()
> advancing by zero forever (sashiko).
> - Patch 4: moved the cxl_cper_post_prot_err() declaration inside the
> CONFIG_ACPI_APEI_GHES block in <acpi/ghes.h> (Shuai Xue).
> - Patch 6: warn instead of returning silently on a short PCIe section (Shuai
> Xue), and added the Closes: link v3 omitted.
> - Patch 7: corrected the Fixes tag to e778ffefa34d, the commit that added the
> "#ifdef ACPI_APEI_PCIEAER" guard, and dropped its Reported-by; sashiko-bot
> reviewed that patch rather than reporting the typo.
> - Patch 9: made the two prot-err length messages distinguishable; both printed
> the same text. The second now reports dvsec_len (Shuai Xue).
> - New patch 10: read only validated fields in cper_mem_err_pack(). It copied
> extended, rank, mem_array_handle and mem_dev_handle unconditionally from
> offsets 73 to 79, past the end of the 73-byte UEFI 2.1/2.2 layout (sashiko).
> - Patch 11: derive the required length from the claimed validation bits. A
> single size gets it wrong both ways (sashiko). Reviewed-by dropped; the
> check gained a helper and is no longer the one Alison and Shuai reviewed.
> - New patch 13: make cxl_cper_handle_prot_err() static. Patch 4 removed its
> last external caller.
>
> Dave Jiang (13):
> efi/cper: Reject CPER records with an out-of-range error_data_length
> efi/cper: Reject an error status block length that wraps a u32
> ACPI: extlog: Validate elog record length before walking sections
> ACPI: extlog: Defer CXL protocol error handling to avoid lock
> inversion
> ACPI: extlog: Avoid populating software AER metadata from raw hardware
> buffer
> ACPI: extlog: Validate PCIe error section length before payload access
> ACPI: extlog: Fix CONFIG_ACPI_APEI_PCIEAER guard typo
> ACPI: APEI: GHES: Bound CXL event record copy to the firmware section
> length
> ACPI: APEI: GHES: Validate CXL protocol error section length before
> RAS cap copy
> efi/cper: Read only validated fields in cper_mem_err_pack()
> ACPI: APEI: GHES: Validate memory error section length before payload
> access
> ACPI: APEI: GHES: Bound AER info copy and sanitize software metadata
> cxl/ras: Make cxl_cper_handle_prot_err() static
>
> drivers/acpi/acpi_extlog.c | 64 +++++++++++++---------
> drivers/acpi/apei/ghes.c | 92 +++++++++++++++++++++++++++-----
> drivers/acpi/apei/ghes_helpers.c | 18 ++++++-
> drivers/cxl/core/ras.c | 3 +-
> drivers/firmware/efi/cper.c | 51 +++++++++++++++---
> include/acpi/ghes.h | 4 ++
> include/cxl/event.h | 6 +--
> 7 files changed, 186 insertions(+), 52 deletions(-)
Sashiko has still reported a finding (medium-level) in patch [5/13]:
https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang%40intel.com
but since the entire series has been reviewed by humans, I'm going to
apply it as is for 7.4 and if you think that the potential issue
pointed out in the above is worth taking care of, please send a
follow-up fix patch (which also applies to the pre-existing issues
reported there).
Thanks!
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko
2026-09-04 18:21 ` [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Rafael J. Wysocki (Intel)
@ 2026-09-04 19:44 ` Dave Jiang
0 siblings, 0 replies; 25+ messages in thread
From: Dave Jiang @ 2026-09-04 19:44 UTC (permalink / raw)
To: Rafael J. Wysocki (Intel)
Cc: linux-acpi, linux-cxl, tony.luck, bp, guohanjun, mchehab,
xueshuai, terry.bowman, benjamin.cheatham, alison.schofield,
Jonathan Cameron
On 9/4/26 11:21 AM, Rafael J. Wysocki (Intel) wrote:
> On Fri, Sep 4, 2026 at 7:23 PM Dave Jiang <dave.jiang@intel.com> wrote:
>>
>> Fixes for pre-existing issues sashiko-bot found while reviewing patches in the
>> CPER, extlog and GHES paths. v1 through v3 fixed successive batches as the
>> review widened; see the links below.
>>
>> The series is grouped in three parts, plus a cleanup.
>>
>> Bound the record before anything walks it:
>>
>> 1/13: Reject CPER records with an out-of-range error_data_length.
>> 2/13: Reject an error status block length that wraps a u32.
>> 3/13: Validate the extlog record length before walking sections.
>>
>> Fix the extlog error paths, then enable them:
>>
>> 4/13: Defer CXL protocol error handling to avoid a lock inversion.
>> 5/13: Avoid populating software AER metadata from the raw hardware buffer.
>> 6/13: Validate the PCIe error section length before payload access.
>> 7/13: Fix the CONFIG_ACPI_APEI_PCIEAER guard typo in extlog.c.
>>
>> Bound each section payload before its consumers read it:
>>
>> 8/13: Bound the CXL event record copy to the firmware section length.
>> 9/13: Validate the CXL protocol error section length before the RAS cap copy.
>> 10/13: Read only validated fields in cper_mem_err_pack().
>> 11/13: Validate the memory error section length before payload access.
>> 12/13: Bound the AER info copy and sanitize software metadata in ghes.c.
>>
>> Then drop an export patch 4 made redundant:
>>
>> 13/13: Make cxl_cper_handle_prot_err() static.
>>
>> Patches 1, 2 and 10 touch drivers/firmware/efi/cper.c, closing the holes at
>> the shared choke point the rest of the series relies on. Patch 2 also fixes an
>> infinite loop in bert_print_all(), unrelated to this series but the same root
>> cause.
>>
>> Known gaps, left for separate patches:
>>
>> - cxl_cper_print_prot_err() in drivers/firmware/efi/cper_cxl.c uses
>> dvsec_len without bounding it against the section length.
>> - cxl_rch_get_aer_info() in drivers/cxl/core/ras_rch.c reads the RCH AER
>> capability from MMIO without clearing header_len/flit, the same class as
>> patches 5 and 12. In the same file, cxl_rch_get_aer_severity() tests
>> PCI_ERR_ROOT_FATAL_RCV against uncor_status, where that bit is
>> PCI_ERR_UNC_FCP.
>> - struct pcie_tlp_log grew to 60 bytes for Flit mode, so the 96-byte CPER
>> AER info no longer maps 1:1 onto struct aer_capability_regs past the
>> Header Log. Patches 5 and 12 now copy the part that maps and place the TLP
>> Prefix Log from its own offset, which covers every field the print path
>> reads - but nothing here decodes the Flit-mode header DWORDs, which reuse
>> those same prefix registers at payload offset 56 while the struct expects
>> dw[4..13] at 44. Doing that properly wants a field-by-field mapping
>> shared with cxl_rch_get_aer_info(), plus a clamp: pcie_print_tlp_log()
>> trusts header_len against a 14-entry dw[], and PCI_ERR_CAP_TLP_LOG_SIZE
>> is five bits wide.
>>
>> v1: https://lore.kernel.org/linux-cxl/20260709162807.1957783-1-dave.jiang@intel.com/
>> v2: https://lore.kernel.org/linux-cxl/20260714231835.303081-1-dave.jiang@intel.com/
>> v3: https://lore.kernel.org/linux-cxl/20260717161647.1493259-1-dave.jiang@intel.com/
>> v4: https://lore.kernel.org/linux-cxl/20260824174936.939059-1-dave.jiang@intel.com/
>> v5: https://lore.kernel.org/linux-cxl/20260827203726.3027541-1-dave.jiang@intel.com/
>>
>> Changes since v5
>> ----------------
>> - Patches 5 and 12: also place the TLP Prefix Log from its own hardware
>> offset rather than leaving it zero. Shortening the copy in v5 dropped it,
>> and it is the one field the print path still reads (sashiko). Alison's and
>> Shuai's Reviewed-by are kept on both, since the intent and location have
>> not changed.
>>
>> Changes since v4
>> ----------------
>> - Patch 1: use check_add_overflow() instead of a u64 sum plus an INT_MAX
>> test, and drop the now-redundant acpi_hest_get_size() bound, since
>> record_size is never smaller than the header (Jonathan Cameron).
>> - Patches 5 and 12: copy only the 44 bytes of aer_info that map onto struct
>> aer_capability_regs - the leading registers and the four Header Log DWORDs
>> - and leave the rest zero, instead of copying all 96 bytes and then
>> clearing header_len and flit (Jonathan Cameron). That also keeps the Root
>> Error Command, Root Error Status and Error Source ID out of
>> header_log.prefix[], where pcie_print_tlp_log() was printing them as
>> end-to-end prefixes.
>> - Patch 3: kept the length bound ahead of cper_estatus_check() and expanded
>> the comment to say why. Swapping them would let cper_estatus_check() walk
>> sections over an unbounded data_length, past the end of elog_buf
>> (Jonathan Cameron).
>> - Condensed the commit logs and comments again; prose only.
>>
>> Changes since v3
>> ----------------
>> - Regrouped into three parts: bound the record, fix and enable the extlog
>> paths, then bound each section payload. v3 interleaved them, so patch 1
>> checked a section before the patch establishing that contract. No code
>> changed.
>> - Moved the extlog lock inversion fix (patch 4) ahead of the CXL protocol
>> error length validation (patch 9). The former deletes
>> extlog_cxl_cper_handle_prot_err(), which the v3 order plumbed a new len
>> argument through three patches before removing it. No functional change.
>> - Patch 1: bound the sum rather than the u32 error_data_length, so the check
>> does not depend on the <acpi/ghes.h> helpers behaving. The v3 "< 0" check
>> was dead code (Tony Luck, Shuai Xue). Reviewed-by dropped; not the same
>> check.
>> - New patch 2: reject an error status block length that wraps the u32 sum in
>> cper_estatus_len(). A data_length of 0xffffffec makes it read back as 0,
>> slipping past the extlog bound in patch 3 and leaving bert_print_all()
>> advancing by zero forever (sashiko).
>> - Patch 4: moved the cxl_cper_post_prot_err() declaration inside the
>> CONFIG_ACPI_APEI_GHES block in <acpi/ghes.h> (Shuai Xue).
>> - Patch 6: warn instead of returning silently on a short PCIe section (Shuai
>> Xue), and added the Closes: link v3 omitted.
>> - Patch 7: corrected the Fixes tag to e778ffefa34d, the commit that added the
>> "#ifdef ACPI_APEI_PCIEAER" guard, and dropped its Reported-by; sashiko-bot
>> reviewed that patch rather than reporting the typo.
>> - Patch 9: made the two prot-err length messages distinguishable; both printed
>> the same text. The second now reports dvsec_len (Shuai Xue).
>> - New patch 10: read only validated fields in cper_mem_err_pack(). It copied
>> extended, rank, mem_array_handle and mem_dev_handle unconditionally from
>> offsets 73 to 79, past the end of the 73-byte UEFI 2.1/2.2 layout (sashiko).
>> - Patch 11: derive the required length from the claimed validation bits. A
>> single size gets it wrong both ways (sashiko). Reviewed-by dropped; the
>> check gained a helper and is no longer the one Alison and Shuai reviewed.
>> - New patch 13: make cxl_cper_handle_prot_err() static. Patch 4 removed its
>> last external caller.
>>
>> Dave Jiang (13):
>> efi/cper: Reject CPER records with an out-of-range error_data_length
>> efi/cper: Reject an error status block length that wraps a u32
>> ACPI: extlog: Validate elog record length before walking sections
>> ACPI: extlog: Defer CXL protocol error handling to avoid lock
>> inversion
>> ACPI: extlog: Avoid populating software AER metadata from raw hardware
>> buffer
>> ACPI: extlog: Validate PCIe error section length before payload access
>> ACPI: extlog: Fix CONFIG_ACPI_APEI_PCIEAER guard typo
>> ACPI: APEI: GHES: Bound CXL event record copy to the firmware section
>> length
>> ACPI: APEI: GHES: Validate CXL protocol error section length before
>> RAS cap copy
>> efi/cper: Read only validated fields in cper_mem_err_pack()
>> ACPI: APEI: GHES: Validate memory error section length before payload
>> access
>> ACPI: APEI: GHES: Bound AER info copy and sanitize software metadata
>> cxl/ras: Make cxl_cper_handle_prot_err() static
>>
>> drivers/acpi/acpi_extlog.c | 64 +++++++++++++---------
>> drivers/acpi/apei/ghes.c | 92 +++++++++++++++++++++++++++-----
>> drivers/acpi/apei/ghes_helpers.c | 18 ++++++-
>> drivers/cxl/core/ras.c | 3 +-
>> drivers/firmware/efi/cper.c | 51 +++++++++++++++---
>> include/acpi/ghes.h | 4 ++
>> include/cxl/event.h | 6 +--
>> 7 files changed, 186 insertions(+), 52 deletions(-)
>
> Sashiko has still reported a finding (medium-level) in patch [5/13]:
>
> https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang%40intel.com
>
> but since the entire series has been reviewed by humans, I'm going to
> apply it as is for 7.4 and if you think that the potential issue
> pointed out in the above is worth taking care of, please send a
> follow-up fix patch (which also applies to the pre-existing issues
> reported there).
You can apply as is. I have a follow on patch to address the issue raised. Thank you!>
> Thanks!
>
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2026-09-04 19:44 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 17:23 [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Dave Jiang
2026-09-04 17:23 ` [PATCH v6 01/13] efi/cper: Reject CPER records with an out-of-range error_data_length Dave Jiang
2026-09-04 17:39 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 02/13] efi/cper: Reject an error status block length that wraps a u32 Dave Jiang
2026-09-04 17:38 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 03/13] ACPI: extlog: Validate elog record length before walking sections Dave Jiang
2026-09-04 17:40 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 04/13] ACPI: extlog: Defer CXL protocol error handling to avoid lock inversion Dave Jiang
2026-09-04 17:23 ` [PATCH v6 05/13] ACPI: extlog: Avoid populating software AER metadata from raw hardware buffer Dave Jiang
2026-09-04 17:58 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 06/13] ACPI: extlog: Validate PCIe error section length before payload access Dave Jiang
2026-09-04 17:23 ` [PATCH v6 07/13] ACPI: extlog: Fix CONFIG_ACPI_APEI_PCIEAER guard typo Dave Jiang
2026-09-04 17:23 ` [PATCH v6 08/13] ACPI: APEI: GHES: Bound CXL event record copy to the firmware section length Dave Jiang
2026-09-04 17:23 ` [PATCH v6 09/13] ACPI: APEI: GHES: Validate CXL protocol error section length before RAS cap copy Dave Jiang
2026-09-04 18:05 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 10/13] efi/cper: Read only validated fields in cper_mem_err_pack() Dave Jiang
2026-09-04 18:09 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 11/13] ACPI: APEI: GHES: Validate memory error section length before payload access Dave Jiang
2026-09-04 18:12 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 12/13] ACPI: APEI: GHES: Bound AER info copy and sanitize software metadata Dave Jiang
2026-09-04 18:08 ` sashiko-bot
2026-09-04 17:23 ` [PATCH v6 13/13] cxl/ras: Make cxl_cper_handle_prot_err() static Dave Jiang
2026-09-04 18:16 ` sashiko-bot
2026-09-04 18:21 ` [PATCH v6 00/13] ACPI: APEI: GHES: Collection of fixes for issues reported by sashiko Rafael J. Wysocki (Intel)
2026-09-04 19:44 ` Dave Jiang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox