* [PATCH v4 0/4] apei/ghes: don't OOPS with bad ARM error CPER records
@ 2026-01-06 10:01 Mauro Carvalho Chehab
2026-01-06 10:01 ` [PATCH v4 2/4] efi/cper: don't go past the ARM processor CPER record buffer Mauro Carvalho Chehab
2026-01-06 10:01 ` [PATCH v4 4/4] efi/cper: don't dump the entire memory region Mauro Carvalho Chehab
0 siblings, 2 replies; 3+ messages in thread
From: Mauro Carvalho Chehab @ 2026-01-06 10:01 UTC (permalink / raw)
To: Rafael J. Wysocki, Robert Moore
Cc: Mauro Carvalho Chehab, Ard Biesheuvel, Ankit Agrawal,
Borislav Petkov, Breno Leitao, Dan Williams, Dave Jiang,
Gregory Price, Hanjun Guo, Jason Tian, Jonathan Cameron,
Jonathan Cameron, Len Brown, Mauro Carvalho Chehab, Shuai Xue,
Smita Koralahalli, Tony Luck, acpica-devel, linux-acpi,
linux-edac, linux-efi, linux-kernel, pengdonglin
Rafael,
Current parsing logic at apei/ghes for ARM Processor Error
assumes that the record sizes are correct. Yet, a bad BIOS
might produce malformed GHES reports.
Worse than that, it may end exposing data from other memory
addresses, as the logic may end dumping large portions of
the memory.
Avoid that by checking the buffer sizes where needed.
---
v4:
- addressed Jonathan comments;
- added two extra patches to prevent other OOM issues.
v3:
- addressed Shuai feedback;
- moved all ghes code to one patch;
- fixed a typo and a bad indent;
- cleanup the size check logic at ghes.c.
Mauro Carvalho Chehab (4):
apei/ghes: ARM processor Error: don't go past allocated memory
efi/cper: don't go past the ARM processor CPER record buffer
apei/ghes: ensure that won't go past CPER allocated record
efi/cper: don't dump the entire memory region
drivers/acpi/apei/ghes.c | 38 ++++++++++++++++++++++++++++-----
drivers/firmware/efi/cper-arm.c | 12 +++++++----
drivers/firmware/efi/cper.c | 8 ++++++-
drivers/ras/ras.c | 6 +++++-
include/acpi/ghes.h | 1 +
include/linux/cper.h | 3 ++-
6 files changed, 56 insertions(+), 12 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v4 2/4] efi/cper: don't go past the ARM processor CPER record buffer
2026-01-06 10:01 [PATCH v4 0/4] apei/ghes: don't OOPS with bad ARM error CPER records Mauro Carvalho Chehab
@ 2026-01-06 10:01 ` Mauro Carvalho Chehab
2026-01-06 10:01 ` [PATCH v4 4/4] efi/cper: don't dump the entire memory region Mauro Carvalho Chehab
1 sibling, 0 replies; 3+ messages in thread
From: Mauro Carvalho Chehab @ 2026-01-06 10:01 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Mauro Carvalho Chehab, Dan Williams, Dave Jiang, Gregory Price,
Jonathan Cameron, Smita Koralahalli, linux-efi, linux-kernel
There's a logic inside ghes/cper to detect if the section_length
is too small, but it doesn't detect if it is too big.
Currently, if the firmware receives an ARM processor CPER record
stating that a section length is big, kernel will blindly trust
section_length, producing a very long dump. For instance, a 67
bytes record with ERR_INFO_NUM set 46198 and section length
set to 854918320 would dump a lot of data going a way past the
firmware memory-mapped area.
Fix it by adding a logic to prevent it to go past the buffer
if ERR_INFO_NUM is too big, making it report instead:
[Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 1
[Hardware Error]: event severity: recoverable
[Hardware Error]: Error 0, type: recoverable
[Hardware Error]: section_type: ARM processor error
[Hardware Error]: MIDR: 0xff304b2f8476870a
[Hardware Error]: section length: 854918320, CPER size: 67
[Hardware Error]: section length is too big
[Hardware Error]: firmware-generated error record is incorrect
[Hardware Error]: ERR_INFO_NUM is 46198
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
---
drivers/firmware/efi/cper-arm.c | 12 ++++++++----
drivers/firmware/efi/cper.c | 3 ++-
include/linux/cper.h | 3 ++-
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/firmware/efi/cper-arm.c b/drivers/firmware/efi/cper-arm.c
index 76542a53e202..b21cb1232d82 100644
--- a/drivers/firmware/efi/cper-arm.c
+++ b/drivers/firmware/efi/cper-arm.c
@@ -226,7 +226,8 @@ static void cper_print_arm_err_info(const char *pfx, u32 type,
}
void cper_print_proc_arm(const char *pfx,
- const struct cper_sec_proc_arm *proc)
+ const struct cper_sec_proc_arm *proc,
+ u32 length)
{
int i, len, max_ctx_type;
struct cper_arm_err_info *err_info;
@@ -238,9 +239,12 @@ void cper_print_proc_arm(const char *pfx,
len = proc->section_length - (sizeof(*proc) +
proc->err_info_num * (sizeof(*err_info)));
- if (len < 0) {
- printk("%ssection length: %d\n", pfx, proc->section_length);
- printk("%ssection length is too small\n", pfx);
+
+ if (len < 0 || proc->section_length > length) {
+ printk("%ssection length: %d, CPER size: %d\n",
+ pfx, proc->section_length, length);
+ printk("%ssection length is too %s\n", pfx,
+ (len < 0) ? "small" : "big");
printk("%sfirmware-generated error record is incorrect\n", pfx);
printk("%sERR_INFO_NUM is %d\n", pfx, proc->err_info_num);
return;
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 0232bd040f61..88fc0293f876 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -659,7 +659,8 @@ cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata
printk("%ssection_type: ARM processor error\n", newpfx);
if (gdata->error_data_length >= sizeof(*arm_err))
- cper_print_proc_arm(newpfx, arm_err);
+ cper_print_proc_arm(newpfx, arm_err,
+ gdata->error_data_length);
else
goto err_section_too_small;
#endif
diff --git a/include/linux/cper.h b/include/linux/cper.h
index 5b1236d8c65b..440b35e459e5 100644
--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -595,7 +595,8 @@ void cper_mem_err_pack(const struct cper_sec_mem_err *,
const char *cper_mem_err_unpack(struct trace_seq *,
struct cper_mem_err_compact *);
void cper_print_proc_arm(const char *pfx,
- const struct cper_sec_proc_arm *proc);
+ const struct cper_sec_proc_arm *proc,
+ u32 length);
void cper_print_proc_ia(const char *pfx,
const struct cper_sec_proc_ia *proc);
int cper_mem_err_location(struct cper_mem_err_compact *mem, char *msg);
--
2.52.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v4 4/4] efi/cper: don't dump the entire memory region
2026-01-06 10:01 [PATCH v4 0/4] apei/ghes: don't OOPS with bad ARM error CPER records Mauro Carvalho Chehab
2026-01-06 10:01 ` [PATCH v4 2/4] efi/cper: don't go past the ARM processor CPER record buffer Mauro Carvalho Chehab
@ 2026-01-06 10:01 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 3+ messages in thread
From: Mauro Carvalho Chehab @ 2026-01-06 10:01 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: Mauro Carvalho Chehab, linux-efi, linux-kernel
The current logic at cper_print_fw_err() doesn't check if the
error record length is big enough to handle offset. On a bad firmware,
if the ofset is above the actual record, length -= offset will
underflow, making it dump the entire memory.
The end result can be:
- the logic taking a lot of time dumping large regions of memory;
- data disclosure due to the memory dumps;
- an OOPS, if it tries to dump an unmapped memory region.
Fix it by checking if the section length is too small before doing
a hex dump.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
drivers/firmware/efi/cper.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 88fc0293f876..0e938fc5ccb1 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -560,6 +560,11 @@ static void cper_print_fw_err(const char *pfx,
} else {
offset = sizeof(*fw_err);
}
+ if (offset > length) {
+ printk("%s""error section length is too small: offset=%d, length=%d\n",
+ pfx, offset, length);
+ return;
+ }
buf += offset;
length -= offset;
--
2.52.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-01-06 10:01 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-06 10:01 [PATCH v4 0/4] apei/ghes: don't OOPS with bad ARM error CPER records Mauro Carvalho Chehab
2026-01-06 10:01 ` [PATCH v4 2/4] efi/cper: don't go past the ARM processor CPER record buffer Mauro Carvalho Chehab
2026-01-06 10:01 ` [PATCH v4 4/4] efi/cper: don't dump the entire memory region Mauro Carvalho Chehab
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox