From 6c705851499172c0ce863e816946fb5a564ff69f Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 14 Aug 2025 09:17:06 -0700 Subject: [PATCH 1/4] ACPI: APEI: EINJ: Check if user asked for EINJV2 injection On an EINJV2 capable system, users may still use the old injection interface but einj_get_parameter_address() takes the EINJV2 path to map the parameter structure. This results in the address the user supplied being stored to the wrong location and the BIOS injecting based on an uninitialized field (0x0 in the reported case). Check the version of the request when mapping the EINJ parameter structure in BIOS reserved memory. Fixes: 691a0f0a557b ("ACPI: APEI: EINJ: Discover EINJv2 parameters") Reported-by: Lai, Yi1 Signed-off-by: Tony Luck Reviewed-by: Zaid Alali Reviewed-by: Hanjun Guo Link: https://patch.msgid.link/20250814161706.4489-1-tony.luck@intel.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/einj-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c index bf8dc92a373a..99f1b841fba9 100644 --- a/drivers/acpi/apei/einj-core.c +++ b/drivers/acpi/apei/einj-core.c @@ -315,7 +315,7 @@ static void __iomem *einj_get_parameter_address(void) memcpy_fromio(&v5param, p, v5param_size); acpi5 = 1; check_vendor_extension(pa_v5, &v5param); - if (available_error_type & ACPI65_EINJV2_SUPP) { + if (is_v2 && available_error_type & ACPI65_EINJV2_SUPP) { len = v5param.einjv2_struct.length; offset = offsetof(struct einjv2_extension_struct, component_arr); max_nr_components = (len - offset) / From 7459e87ae1d78ba27b728172fa2aa912a5b8640d Mon Sep 17 00:00:00 2001 From: Charles Han Date: Fri, 15 Aug 2025 10:42:06 +0800 Subject: [PATCH 2/4] ACPI: APEI: EINJ: fix potential NULL dereference in __einj_error_inject() The __einj_error_inject() function allocates memory via kmalloc() without checking for allocation failure, which could lead to a NULL pointer dereference. Return -ENOMEM in case allocation fails. Fixes: b47610296d17 ("ACPI: APEI: EINJ: Enable EINJv2 error injections") Signed-off-by: Charles Han Reviewed-by: Tony Luck Reviewed-by: Hanjun Guo Link: https://patch.msgid.link/20250815024207.3038-1-hanchunchao@inspur.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/einj-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c index 99f1b841fba9..b489ae684a1b 100644 --- a/drivers/acpi/apei/einj-core.c +++ b/drivers/acpi/apei/einj-core.c @@ -540,6 +540,9 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, struct set_error_type_with_address *v5param; v5param = kmalloc(v5param_size, GFP_KERNEL); + if (!v5param) + return -ENOMEM; + memcpy_fromio(v5param, einj_param, v5param_size); v5param->type = type; if (type & ACPI5_VENDOR_BIT) { From b21d1fbb97c814c76ffa392cd603f8cd3ecc0355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 14 Aug 2025 07:11:57 +0200 Subject: [PATCH 3/4] ACPI: APEI: EINJ: Fix resource leak by remove callback in .exit.text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback is also used during error handling in faux_probe(). As einj_remove() was marked with __exit it's not linked into the kernel if the driver is built-in, potentially resulting in resource leaks. Also remove the comment justifying the __exit annotation which doesn't apply any more since the driver was converted to the faux device interface. Fixes: 6cb9441bfe8d ("ACPI: APEI: EINJ: Transition to the faux device interface") Signed-off-by: Uwe Kleine-König Cc: 6.16+ # 6.16+ Link: https://patch.msgid.link/20250814051157.35867-2-u.kleine-koenig@baylibre.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/einj-core.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c index b489ae684a1b..2561b045acc7 100644 --- a/drivers/acpi/apei/einj-core.c +++ b/drivers/acpi/apei/einj-core.c @@ -1094,7 +1094,7 @@ static int __init einj_probe(struct faux_device *fdev) return rc; } -static void __exit einj_remove(struct faux_device *fdev) +static void einj_remove(struct faux_device *fdev) { struct apei_exec_context ctx; @@ -1117,15 +1117,9 @@ static void __exit einj_remove(struct faux_device *fdev) } static struct faux_device *einj_dev; -/* - * einj_remove() lives in .exit.text. For drivers registered via - * platform_driver_probe() this is ok because they cannot get unbound at - * runtime. So mark the driver struct with __refdata to prevent modpost - * triggering a section mismatch warning. - */ -static struct faux_device_ops einj_device_ops __refdata = { +static struct faux_device_ops einj_device_ops = { .probe = einj_probe, - .remove = __exit_p(einj_remove), + .remove = einj_remove, }; static int __init einj_init(void) From 8151320c747efb22d30b035af989fed0d502176e Mon Sep 17 00:00:00 2001 From: Chen Yu Date: Tue, 22 Jul 2025 22:32:33 +0800 Subject: [PATCH 4/4] ACPI: pfr_update: Fix the driver update version check The security-version-number check should be used rather than the runtime version check for driver updates. Otherwise, the firmware update would fail when the update binary had a lower runtime version number than the current one. Fixes: 0db89fa243e5 ("ACPI: Introduce Platform Firmware Runtime Update device driver") Cc: 5.17+ # 5.17+ Reported-by: "Govindarajulu, Hariganesh" Signed-off-by: Chen Yu Link: https://patch.msgid.link/20250722143233.3970607-1-yu.c.chen@intel.com [ rjw: Changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/pfr_update.c | 2 +- include/uapi/linux/pfrut.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/pfr_update.c b/drivers/acpi/pfr_update.c index 318683744ed1..11b1c2828005 100644 --- a/drivers/acpi/pfr_update.c +++ b/drivers/acpi/pfr_update.c @@ -329,7 +329,7 @@ static bool applicable_image(const void *data, struct pfru_update_cap_info *cap, if (type == PFRU_CODE_INJECT_TYPE) return payload_hdr->rt_ver >= cap->code_rt_version; - return payload_hdr->rt_ver >= cap->drv_rt_version; + return payload_hdr->svn_ver >= cap->drv_svn; } static void print_update_debug_info(struct pfru_updated_result *result, diff --git a/include/uapi/linux/pfrut.h b/include/uapi/linux/pfrut.h index 42fa15f8310d..b77d5c210c26 100644 --- a/include/uapi/linux/pfrut.h +++ b/include/uapi/linux/pfrut.h @@ -89,6 +89,7 @@ struct pfru_payload_hdr { __u32 hw_ver; __u32 rt_ver; __u8 platform_id[16]; + __u32 svn_ver; }; enum pfru_dsm_status {