From b9badc2d5ccd425b778a4b6c90e759c93e49cf41 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Tue, 29 Oct 2024 16:58:13 +0800 Subject: [PATCH 1/2] ACPI: battery: Simplify battery hook locking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stable inclusion from stable-v5.10.227 commit 20557232c91adf2fd10b6abfc148ce9218af73e0 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAYRCN CVE: CVE-2024-49955 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=20557232c91adf2fd10b6abfc148ce9218af73e0 -------------------------------- [ Upstream commit 86309cbed26139e1caae7629dcca1027d9a28e75 ] Move the conditional locking from __battery_hook_unregister() into battery_hook_unregister() and rename the low-level function to simplify the locking during battery hook removal. Reviewed-by: Ilpo Järvinen Reviewed-by: Pali Rohár Signed-off-by: Armin Wolf Link: https://patch.msgid.link/20241001212835.341788-2-W_Armin@gmx.de Signed-off-by: Rafael J. Wysocki Stable-dep-of: 76959aff14a0 ("ACPI: battery: Fix possible crash when unregistering a battery hook") Signed-off-by: Sasha Levin Signed-off-by: liwei --- drivers/acpi/battery.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 8b43efe97da5..1e782e332073 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -689,27 +689,27 @@ static LIST_HEAD(acpi_battery_list); static LIST_HEAD(battery_hook_list); static DEFINE_MUTEX(hook_mutex); -static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock) +static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook) { struct acpi_battery *battery; + /* * In order to remove a hook, we first need to * de-register all the batteries that are registered. */ - if (lock) - mutex_lock(&hook_mutex); list_for_each_entry(battery, &acpi_battery_list, list) { hook->remove_battery(battery->bat); } list_del(&hook->list); - if (lock) - mutex_unlock(&hook_mutex); + pr_info("extension unregistered: %s\n", hook->name); } void battery_hook_unregister(struct acpi_battery_hook *hook) { - __battery_hook_unregister(hook, 1); + mutex_lock(&hook_mutex); + battery_hook_unregister_unlocked(hook); + mutex_unlock(&hook_mutex); } EXPORT_SYMBOL_GPL(battery_hook_unregister); @@ -735,7 +735,7 @@ void battery_hook_register(struct acpi_battery_hook *hook) * hooks. */ pr_err("extension failed to load: %s", hook->name); - __battery_hook_unregister(hook, 0); + battery_hook_unregister_unlocked(hook); goto end; } } @@ -772,7 +772,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery) */ pr_err("error in extension, unloading: %s", hook_node->name); - __battery_hook_unregister(hook_node, 0); + battery_hook_unregister_unlocked(hook_node); } } mutex_unlock(&hook_mutex); @@ -805,7 +805,7 @@ static void __exit battery_hook_exit(void) * need to remove the hooks. */ list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) { - __battery_hook_unregister(hook, 1); + battery_hook_unregister(hook); } mutex_destroy(&hook_mutex); } -- Gitee From 817ea23eb0dbd5ae331245ceab74d8fee02bd941 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Tue, 29 Oct 2024 16:58:14 +0800 Subject: [PATCH 2/2] ACPI: battery: Fix possible crash when unregistering a battery hook stable inclusion from stable-v5.10.227 commit da964de4c18199e14b961b5b2e5e6570552a313c category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAYRCN CVE: CVE-2024-49955 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=da964de4c18199e14b961b5b2e5e6570552a313c -------------------------------- [ Upstream commit 76959aff14a0012ad6b984ec7686d163deccdc16 ] When a battery hook returns an error when adding a new battery, then the battery hook is automatically unregistered. However the battery hook provider cannot know that, so it will later call battery_hook_unregister() on the already unregistered battery hook, resulting in a crash. Fix this by using the list head to mark already unregistered battery hooks as already being unregistered so that they can be ignored by battery_hook_unregister(). Fixes: fa93854f7a7e ("battery: Add the battery hooking API") Signed-off-by: Armin Wolf Link: https://patch.msgid.link/20241001212835.341788-3-W_Armin@gmx.de Cc: All applicable Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Signed-off-by: liwei --- drivers/acpi/battery.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 1e782e332073..04ecda0d8560 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -700,7 +700,7 @@ static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook) list_for_each_entry(battery, &acpi_battery_list, list) { hook->remove_battery(battery->bat); } - list_del(&hook->list); + list_del_init(&hook->list); pr_info("extension unregistered: %s\n", hook->name); } @@ -708,7 +708,14 @@ static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook) void battery_hook_unregister(struct acpi_battery_hook *hook) { mutex_lock(&hook_mutex); - battery_hook_unregister_unlocked(hook); + /* + * Ignore already unregistered battery hooks. This might happen + * if a battery hook was previously unloaded due to an error when + * adding a new battery. + */ + if (!list_empty(&hook->list)) + battery_hook_unregister_unlocked(hook); + mutex_unlock(&hook_mutex); } EXPORT_SYMBOL_GPL(battery_hook_unregister); @@ -718,7 +725,6 @@ void battery_hook_register(struct acpi_battery_hook *hook) struct acpi_battery *battery; mutex_lock(&hook_mutex); - INIT_LIST_HEAD(&hook->list); list_add(&hook->list, &battery_hook_list); /* * Now that the driver is registered, we need -- Gitee