From: gregkh@linuxfoundation.org
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Hans de Goede <hdegoede@redhat.com>,
Bob Moore <robert.moore@intel.com>,
Erik Kaneda <erik.kaneda@intel.com>,
"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Subject: [PATCH 5.10 01/49] ACPICA: Fix race in generic_serial_bus (I2C) and GPIO op_region parameter handling
Date: Wed, 10 Mar 2021 14:23:12 +0100 [thread overview]
Message-ID: <20210310132321.997043366@linuxfoundation.org> (raw)
In-Reply-To: <20210310132321.948258062@linuxfoundation.org>
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
From: Hans de Goede <hdegoede@redhat.com>
commit c27f3d011b08540e68233cf56274fdc34bebb9b5 upstream.
ACPICA commit c9e0116952363b0fa815143dca7e9a2eb4fefa61
The handling of the generic_serial_bus (I2C) and GPIO op_regions in
acpi_ev_address_space_dispatch() passes a number of extra parameters
to the address-space handler through the address-space Context pointer
(instead of using more function parameters).
The Context is shared between threads, so if multiple threads try to
call the handler for the same address-space at the same time, then
a second thread could change the parameters of a first thread while
the handler is running for the first thread.
An example of this race hitting is the Lenovo Yoga Tablet2 1015L,
where there are both attrib_bytes accesses and attrib_byte accesses
to the same address-space. The attrib_bytes access stores the number
of bytes to transfer in Context->access_length. Where as for the
attrib_byte access the number of bytes to transfer is always 1 and
field_obj->Field.access_length is unused (so 0). Both types of
accesses racing from different threads leads to the following problem:
1. Thread a. starts an attrib_bytes access, stores a non 0 value
from field_obj->Field.access_length in Context->access_length
2. Thread b. starts an attrib_byte access, stores 0 in
Context->access_length
3. Thread a. calls i2c_acpi_space_handler() (under Linux). Which
sees that the access-type is ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE
and calls acpi_gsb_i2c_read_bytes(..., Context->access_length)
4. At this point Context->access_length is 0 (set by thread b.)
rather then the field_obj->Field.access_length value from thread a.
This 0 length reads leads to the following errors being logged:
i2c i2c-0: adapter quirk: no zero length (addr 0x0078, size 0, read)
i2c i2c-0: i2c read 0 bytes from client@0x78 starting at reg 0x0 failed, error: -95
Note this is just an example of the problems which this race can cause.
There are likely many more (sporadic) problems caused by this race.
This commit adds a new context_mutex to struct acpi_object_addr_handler
and makes acpi_ev_address_space_dispatch() take that mutex when
using the shared Context to pass extra parameters to an address-space
handler, fixing this race.
Note the new mutex must be taken *after* exiting the interpreter,
therefor the existing acpi_ex_exit_interpreter() call is moved to above
the code which stores the extra parameters in the Context.
Link: https://github.com/acpica/acpica/commit/c9e01169
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Erik Kaneda <erik.kaneda@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/acpi/acpica/acobject.h | 1
drivers/acpi/acpica/evhandler.c | 7 ++++
drivers/acpi/acpica/evregion.c | 64 +++++++++++++++++++++++++++++-----------
drivers/acpi/acpica/evxfregn.c | 2 +
4 files changed, 57 insertions(+), 17 deletions(-)
--- a/drivers/acpi/acpica/acobject.h
+++ b/drivers/acpi/acpica/acobject.h
@@ -284,6 +284,7 @@ struct acpi_object_addr_handler {
acpi_adr_space_handler handler;
struct acpi_namespace_node *node; /* Parent device */
void *context;
+ acpi_mutex context_mutex;
acpi_adr_space_setup setup;
union acpi_operand_object *region_list; /* Regions using this handler */
union acpi_operand_object *next;
--- a/drivers/acpi/acpica/evhandler.c
+++ b/drivers/acpi/acpica/evhandler.c
@@ -489,6 +489,13 @@ acpi_ev_install_space_handler(struct acp
/* Init handler obj */
+ status =
+ acpi_os_create_mutex(&handler_obj->address_space.context_mutex);
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(handler_obj);
+ goto unlock_and_exit;
+ }
+
handler_obj->address_space.space_id = (u8)space_id;
handler_obj->address_space.handler_flags = flags;
handler_obj->address_space.region_list = NULL;
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -111,6 +111,8 @@ acpi_ev_address_space_dispatch(union acp
union acpi_operand_object *region_obj2;
void *region_context = NULL;
struct acpi_connection_info *context;
+ acpi_mutex context_mutex;
+ u8 context_locked;
acpi_physical_address address;
ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
@@ -135,6 +137,8 @@ acpi_ev_address_space_dispatch(union acp
}
context = handler_desc->address_space.context;
+ context_mutex = handler_desc->address_space.context_mutex;
+ context_locked = FALSE;
/*
* It may be the case that the region has never been initialized.
@@ -203,6 +207,23 @@ acpi_ev_address_space_dispatch(union acp
handler = handler_desc->address_space.handler;
address = (region_obj->region.address + region_offset);
+ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+ "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
+ ®ion_obj->region.handler->address_space, handler,
+ ACPI_FORMAT_UINT64(address),
+ acpi_ut_get_region_name(region_obj->region.
+ space_id)));
+
+ if (!(handler_desc->address_space.handler_flags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+ /*
+ * For handlers other than the default (supplied) handlers, we must
+ * exit the interpreter because the handler *might* block -- we don't
+ * know what it will do, so we can't hold the lock on the interpreter.
+ */
+ acpi_ex_exit_interpreter();
+ }
+
/*
* Special handling for generic_serial_bus and general_purpose_io:
* There are three extra parameters that must be passed to the
@@ -211,6 +232,11 @@ acpi_ev_address_space_dispatch(union acp
* 2) Length of the above buffer
* 3) Actual access length from the access_as() op
*
+ * Since we pass these extra parameters via the context, which is
+ * shared between threads, we must lock the context to avoid these
+ * parameters being changed from another thread before the handler
+ * has completed running.
+ *
* In addition, for general_purpose_io, the Address and bit_width fields
* are defined as follows:
* 1) Address is the pin number index of the field (bit offset from
@@ -220,6 +246,14 @@ acpi_ev_address_space_dispatch(union acp
if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) &&
context && field_obj) {
+ status =
+ acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE(status)) {
+ goto re_enter_interpreter;
+ }
+
+ context_locked = TRUE;
+
/* Get the Connection (resource_template) buffer */
context->connection = field_obj->field.resource_buffer;
@@ -229,6 +263,14 @@ acpi_ev_address_space_dispatch(union acp
if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) &&
context && field_obj) {
+ status =
+ acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE(status)) {
+ goto re_enter_interpreter;
+ }
+
+ context_locked = TRUE;
+
/* Get the Connection (resource_template) buffer */
context->connection = field_obj->field.resource_buffer;
@@ -238,28 +280,15 @@ acpi_ev_address_space_dispatch(union acp
bit_width = field_obj->field.bit_length;
}
- ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
- "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
- ®ion_obj->region.handler->address_space, handler,
- ACPI_FORMAT_UINT64(address),
- acpi_ut_get_region_name(region_obj->region.
- space_id)));
-
- if (!(handler_desc->address_space.handler_flags &
- ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
- /*
- * For handlers other than the default (supplied) handlers, we must
- * exit the interpreter because the handler *might* block -- we don't
- * know what it will do, so we can't hold the lock on the interpreter.
- */
- acpi_ex_exit_interpreter();
- }
-
/* Call the handler */
status = handler(function, address, bit_width, value, context,
region_obj2->extra.region_context);
+ if (context_locked) {
+ acpi_os_release_mutex(context_mutex);
+ }
+
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]",
acpi_ut_get_region_name(region_obj->region.
@@ -276,6 +305,7 @@ acpi_ev_address_space_dispatch(union acp
}
}
+re_enter_interpreter:
if (!(handler_desc->address_space.handler_flags &
ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
/*
--- a/drivers/acpi/acpica/evxfregn.c
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -201,6 +201,8 @@ acpi_remove_address_space_handler(acpi_h
/* Now we can delete the handler object */
+ acpi_os_release_mutex(handler_obj->address_space.
+ context_mutex);
acpi_ut_remove_reference(handler_obj);
goto unlock_and_exit;
}
next prev parent reply other threads:[~2021-03-10 13:25 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-10 13:23 [PATCH 5.10 00/49] 5.10.23-rc1 review gregkh
2021-03-10 13:23 ` gregkh [this message]
2021-03-10 13:23 ` [PATCH 5.10 02/49] [PATCH v2] ASoC: SOF: Intel: broadwell: fix mutual exclusion with catpt driver gregkh
2021-03-10 13:23 ` [PATCH 5.10 03/49] nvme-pci: mark Kingston SKC2000 as not supporting the deepest power state gregkh
2021-03-10 13:23 ` [PATCH 5.10 04/49] parisc: Enable -mlong-calls gcc option with CONFIG_COMPILE_TEST gregkh
2021-03-10 13:23 ` [PATCH 5.10 05/49] arm64: Make CPU_BIG_ENDIAN depend on ld.bfd or ld.lld 13.0.0+ gregkh
2021-03-10 13:23 ` [PATCH 5.10 06/49] btrfs: export and rename qgroup_reserve_meta gregkh
2021-03-10 13:23 ` [PATCH 5.10 07/49] btrfs: dont flush from btrfs_delayed_inode_reserve_metadata gregkh
2021-03-10 13:23 ` [PATCH 5.10 08/49] iommu/amd: Fix sleeping in atomic in increase_address_space() gregkh
2021-03-10 13:23 ` [PATCH 5.10 09/49] ASoC: intel: sof_rt5682: Add quirk for Dooly gregkh
2021-03-10 13:23 ` [PATCH 5.10 10/49] Bluetooth: btqca: Add valid le states quirk gregkh
2021-03-10 13:23 ` [PATCH 5.10 11/49] mwifiex: pcie: skip cancel_work_sync() on reset failure path gregkh
2021-03-10 13:23 ` [PATCH 5.10 12/49] ASoC: Intel: sof_sdw: add quirk for new TigerLake-SDCA device gregkh
2021-03-10 13:23 ` [PATCH 5.10 13/49] bus: ti-sysc: Implement GPMC debug quirk to drop platform data gregkh
2021-03-10 13:23 ` [PATCH 5.10 14/49] net: ipa: ignore CHANNEL_NOT_RUNNING errors gregkh
2021-03-10 17:36 ` Naresh Kamboju
2021-03-10 17:48 ` Alex Elder
2021-03-10 18:00 ` Greg Kroah-Hartman
2021-03-10 18:27 ` Greg Kroah-Hartman
2021-03-10 13:23 ` [PATCH 5.10 15/49] platform/x86: acer-wmi: Cleanup ACER_CAP_FOO defines gregkh
2021-03-10 13:23 ` [PATCH 5.10 16/49] platform/x86: acer-wmi: Cleanup accelerometer device handling gregkh
2021-03-10 13:23 ` [PATCH 5.10 17/49] platform/x86: acer-wmi: Add new force_caps module parameter gregkh
2021-03-10 13:23 ` [PATCH 5.10 18/49] platform/x86: acer-wmi: Add ACER_CAP_SET_FUNCTION_MODE capability flag gregkh
2021-03-10 13:23 ` [PATCH 5.10 19/49] platform/x86: acer-wmi: Add support for SW_TABLET_MODE on Switch devices gregkh
2021-03-10 13:23 ` [PATCH 5.10 20/49] platform/x86: acer-wmi: Add ACER_CAP_KBD_DOCK quirk for the Aspire Switch 10E SW3-016 gregkh
2021-03-10 13:23 ` [PATCH 5.10 21/49] HID: mf: add support for 0079:1846 Mayflash/Dragonrise USB Gamecube Adapter gregkh
2021-03-10 13:23 ` [PATCH 5.10 22/49] media: cx23885: add more quirks for reset DMA on some AMD IOMMU gregkh
2021-03-10 13:23 ` [PATCH 5.10 23/49] ACPI: video: Add DMI quirk for GIGABYTE GB-BXBT-2807 gregkh
2021-03-10 20:04 ` Pavel Machek
2021-03-10 20:04 ` Pavel Machek
2021-03-11 12:37 ` Greg KH
2021-03-10 13:23 ` [PATCH 5.10 24/49] ASoC: Intel: bytcr_rt5640: Add quirk for ARCHOS Cesium 140 gregkh
2021-03-10 13:23 ` [PATCH 5.10 25/49] usb: cdns3: host: add .suspend_quirk for xhci-plat.c gregkh
2021-03-10 13:23 ` [PATCH 5.10 26/49] usb: cdns3: host: add xhci_plat_priv quirk XHCI_SKIP_PHY_INIT gregkh
2021-03-10 13:23 ` [PATCH 5.10 27/49] usb: cdns3: add quirk for enable runtime pm by default gregkh
2021-03-10 13:23 ` [PATCH 5.10 28/49] usb: cdns3: fix NULL pointer dereference on no platform data gregkh
2021-03-10 13:23 ` [PATCH 5.10 29/49] PCI: Add function 1 DMA alias quirk for Marvell 9215 SATA controller gregkh
2021-03-10 13:23 ` [PATCH 5.10 30/49] KVM: x86: Supplement __cr4_reserved_bits() with X86_FEATURE_PCID check gregkh
2021-03-10 13:23 ` [PATCH 5.10 31/49] ASoC: Intel: sof_sdw: add missing TGL_HDMI quirk for Dell SKU 0A32 gregkh
2021-03-10 13:23 ` [PATCH 5.10 32/49] scsi: ufs-mediatek: Enable UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL gregkh
2021-03-10 13:23 ` [PATCH 5.10 33/49] scsi: ufs: Add a quirk to permit overriding UniPro defaults gregkh
2021-03-10 13:23 ` [PATCH 5.10 34/49] misc: eeprom_93xx46: Add quirk to support Microchip 93LC46B eeprom gregkh
2021-03-10 13:23 ` [PATCH 5.10 35/49] scsi: ufs: Introduce a quirk to allow only page-aligned sg entries gregkh
2021-03-10 13:23 ` [PATCH 5.10 36/49] scsi: ufs: ufs-exynos: Apply vendor-specific values for three timeouts gregkh
2021-03-10 13:23 ` [PATCH 5.10 37/49] scsi: ufs: ufs-exynos: Use UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE gregkh
2021-03-10 13:23 ` [PATCH 5.10 38/49] drm/msm/a5xx: Remove overwriting A5XX_PC_DBG_ECO_CNTL register gregkh
2021-03-10 13:23 ` [PATCH 5.10 39/49] mmc: sdhci-of-dwcmshc: set SDHCI_QUIRK2_PRESET_VALUE_BROKEN gregkh
2021-03-10 13:23 ` [PATCH 5.10 40/49] HID: i2c-hid: Add I2C_HID_QUIRK_NO_IRQ_AFTER_RESET for ITE8568 EC on Voyo Winpad A15 gregkh
2021-03-10 13:23 ` [PATCH 5.10 41/49] ALSA: usb-audio: Add DJM750 to Pioneer mixer quirk gregkh
2021-03-10 13:23 ` [PATCH 5.10 42/49] ALSA: usb-audio: add mixer quirks for Pioneer DJM-900NXS2 gregkh
2021-03-10 13:23 ` [PATCH 5.10 43/49] PCI: cadence: Retrain Link to work around Gen2 training defect gregkh
2021-03-10 13:23 ` [PATCH 5.10 44/49] ASoC: Intel: sof_sdw: reorganize quirks by generation gregkh
2021-03-10 13:23 ` [PATCH 5.10 45/49] ASoC: Intel: sof_sdw: add quirk for HP Spectre x360 convertible gregkh
2021-03-10 13:23 ` [PATCH 5.10 46/49] scsi: ufs: Fix a duplicate dev quirk number gregkh
2021-03-10 13:23 ` [PATCH 5.10 47/49] KVM: SVM: Clear the CR4 register on reset gregkh
2021-03-10 13:23 ` [PATCH 5.10 48/49] nvme-pci: mark Seagate Nytro XM1440 as QUIRK_NO_NS_DESC_LIST gregkh
2021-03-10 13:24 ` [PATCH 5.10 49/49] nvme-pci: add quirks for Lexar 256GB SSD gregkh
2021-03-10 17:38 ` [PATCH 5.10 00/49] 5.10.23-rc1 review Naresh Kamboju
2021-03-10 17:58 ` Guenter Roeck
2021-03-10 18:26 ` Greg Kroah-Hartman
2021-03-10 18:27 ` Greg Kroah-Hartman
2021-03-10 20:00 ` Shuah Khan
2021-03-11 2:38 ` Samuel Zou
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210310132321.997043366@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=erik.kaneda@intel.com \
--cc=hdegoede@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=rafael.j.wysocki@intel.com \
--cc=robert.moore@intel.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox