6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Guangshuo Li [ Upstream commit 9523698252fd583d6987582b9c34ec6500d10986 ] register_platform_devices() registers the battery, LED, and watchdog platform devices in sequence. If LED registration fails, the battery device remains registered. If watchdog registration fails, the LED and battery devices remain registered. These failure paths leave successful platform_device_register_data() calls without the matching platform_device_unregister() calls. Add an unwind ladder to unregister previously registered platform devices in reverse order before returning the registration error. The issue was identified by a static analysis tool I developed and confirmed by manual review. Fixes: dd123e62bded ("platform/x86: simatic-ipc: add main driver for Siemens devices") Cc: stable@vger.kernel.org Signed-off-by: Guangshuo Li Link: https://patch.msgid.link/20260924115617.1578309-1-lgs201920130244@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/siemens/simatic-ipc.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/siemens/simatic-ipc.c b/drivers/platform/x86/siemens/simatic-ipc.c index 7039874d8f112..4a4509fc9263e 100644 --- a/drivers/platform/x86/siemens/simatic-ipc.c +++ b/drivers/platform/x86/siemens/simatic-ipc.c @@ -92,6 +92,7 @@ static int register_platform_devices(u32 station_id) u8 wdtmode = SIMATIC_IPC_DEVICE_NONE; u8 battmode = SIMATIC_IPC_DEVICE_NONE; char *pdevname; + int ret; int i; for (i = 0; i < ARRAY_SIZE(device_modes); i++) { @@ -139,8 +140,10 @@ static int register_platform_devices(u32 station_id) pdevname, PLATFORM_DEVID_NONE, &platform_data, sizeof(struct simatic_ipc_platform)); - if (IS_ERR(ipc_led_platform_device)) - return PTR_ERR(ipc_led_platform_device); + if (IS_ERR(ipc_led_platform_device)) { + ret = PTR_ERR(ipc_led_platform_device); + goto err_unregister_batt; + } pr_debug("device=%s created\n", ipc_led_platform_device->name); @@ -153,8 +156,10 @@ static int register_platform_devices(u32 station_id) KBUILD_MODNAME "_wdt", PLATFORM_DEVID_NONE, &platform_data, sizeof(struct simatic_ipc_platform)); - if (IS_ERR(ipc_wdt_platform_device)) - return PTR_ERR(ipc_wdt_platform_device); + if (IS_ERR(ipc_wdt_platform_device)) { + ret = PTR_ERR(ipc_wdt_platform_device); + goto err_unregister_led; + } pr_debug("device=%s created\n", ipc_wdt_platform_device->name); @@ -169,6 +174,14 @@ static int register_platform_devices(u32 station_id) } return 0; + +err_unregister_led: + if (ledmode != SIMATIC_IPC_DEVICE_NONE) + platform_device_unregister(ipc_led_platform_device); +err_unregister_batt: + if (battmode != SIMATIC_IPC_DEVICE_NONE) + platform_device_unregister(ipc_batt_platform_device); + return ret; } static void request_additional_modules(u32 station_id) -- 2.53.0