summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-12-27 11:04:21 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-10-01 13:14:30 +0200
commit4913d773d113b1f61620baeadaa9d8ef3a4400c1 (patch)
tree2e206db6dd7ac132d00f0cb2c79c002afc41753f
parent479468bef2fa4845cd894ad352181b619195fe70 (diff)
downloadlinux-stable-4913d773d113b1f61620baeadaa9d8ef3a4400c1.tar.gz
linux-stable-4913d773d113b1f61620baeadaa9d8ef3a4400c1.tar.bz2
linux-stable-4913d773d113b1f61620baeadaa9d8ef3a4400c1.zip
ACPI: EC: Reference count query handlers under lock
[ Upstream commit 3df663a147fe077a6ee8444ec626738946e65547 ] There is a race condition in acpi_ec_get_query_handler() theoretically allowing query handlers to go away before refernce counting them. In order to avoid it, call kref_get() on query handlers under ec->mutex. Also simplify the code a bit while at it. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/acpi/ec.c16
1 files changed, 4 insertions, 12 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 49e16f009095..9415a0041aaf 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1081,28 +1081,20 @@ void acpi_ec_dispatch_gpe(void)
Event Management
-------------------------------------------------------------------------- */
static struct acpi_ec_query_handler *
-acpi_ec_get_query_handler(struct acpi_ec_query_handler *handler)
-{
- if (handler)
- kref_get(&handler->kref);
- return handler;
-}
-
-static struct acpi_ec_query_handler *
acpi_ec_get_query_handler_by_value(struct acpi_ec *ec, u8 value)
{
struct acpi_ec_query_handler *handler;
- bool found = false;
mutex_lock(&ec->mutex);
list_for_each_entry(handler, &ec->list, node) {
if (value == handler->query_bit) {
- found = true;
- break;
+ kref_get(&handler->kref);
+ mutex_unlock(&ec->mutex);
+ return handler;
}
}
mutex_unlock(&ec->mutex);
- return found ? acpi_ec_get_query_handler(handler) : NULL;
+ return NULL;
}
static void acpi_ec_query_handler_release(struct kref *kref)