[PATCH v4 10/13] efi/cper: Read only validated fields in cper_mem_err_pack()
Dave Jiang <[email protected]>
| Newsgroups | org.kernel.vger.linux-cxl,org.kernel.vger.linux-acpi |
|---|---|
| Message-ID | <[email protected]> |
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: [email protected] Closes: https://sashiko.dev/#/patchset/[email protected]?part=7 Fixes: 2dfb7d51a61d ("trace, RAS: Add eMCA trace event interface") Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Dave Jiang <[email protected]> --- v4: - New patch. sashiko-bot pointed out that bounding the memory error section at the 73-byte layout still leaves cper_mem_err_pack() reading offsets 73 to 79. --- 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 ea1c999089bc..6c64a0f06a4e 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