From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Lukas Wunner <lukas@wunner.de>,
Bjorn Helgaas <bhelgaas@google.com>
Subject: [PATCH 4.18 18/22] PCI: pciehp: Fix use-after-free on unplug
Date: Thu, 23 Aug 2018 09:56:44 +0200 [thread overview]
Message-ID: <20180823074800.339789967@linuxfoundation.org> (raw)
In-Reply-To: <20180823074759.234685844@linuxfoundation.org>
4.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner <lukas@wunner.de>
commit 281e878eab191cce4259abbbf1a0322e3adae02c upstream.
When pciehp is unbound (e.g. on unplug of a Thunderbolt device), the
hotplug_slot struct is deregistered and thus freed before freeing the
IRQ. The IRQ handler and the work items it schedules print the slot
name referenced from the freed structure in various informational and
debug log messages, each time resulting in a quadruple dereference of
freed pointers (hotplug_slot -> pci_slot -> kobject -> name).
At best the slot name is logged as "(null)", at worst kernel memory is
exposed in logs or the driver crashes:
pciehp 0000:10:00.0:pcie204: Slot((null)): Card not present
An attacker may provoke the bug by unplugging multiple devices on a
Thunderbolt daisy chain at once. Unplugging can also be simulated by
powering down slots via sysfs. The bug is particularly easy to trigger
in poll mode.
It has been present since the driver's introduction in 2004:
https://git.kernel.org/tglx/history/c/c16b4b14d980
Fix by rearranging teardown such that the IRQ is freed first. Run the
work items queued by the IRQ handler to completion before freeing the
hotplug_slot struct by draining the work queue from the ->release_slot
callback which is invoked by pci_hp_deregister().
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org # v2.6.4
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/pci/hotplug/pciehp.h | 1 +
drivers/pci/hotplug/pciehp_core.c | 7 +++++++
drivers/pci/hotplug/pciehp_hpc.c | 5 ++---
3 files changed, 10 insertions(+), 3 deletions(-)
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -119,6 +119,7 @@ int pciehp_unconfigure_device(struct slo
void pciehp_queue_pushbutton_work(struct work_struct *work);
struct controller *pcie_init(struct pcie_device *dev);
int pcie_init_notification(struct controller *ctrl);
+void pcie_shutdown_notification(struct controller *ctrl);
int pciehp_enable_slot(struct slot *p_slot);
int pciehp_disable_slot(struct slot *p_slot);
void pcie_reenable_notification(struct controller *ctrl);
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -62,6 +62,12 @@ static int reset_slot(struct hotplug_slo
*/
static void release_slot(struct hotplug_slot *hotplug_slot)
{
+ struct slot *slot = hotplug_slot->private;
+
+ /* queued work needs hotplug_slot name */
+ cancel_delayed_work(&slot->work);
+ drain_workqueue(slot->wq);
+
kfree(hotplug_slot->ops);
kfree(hotplug_slot->info);
kfree(hotplug_slot);
@@ -264,6 +270,7 @@ static void pciehp_remove(struct pcie_de
{
struct controller *ctrl = get_service_data(dev);
+ pcie_shutdown_notification(ctrl);
cleanup_slot(ctrl);
pciehp_release_ctrl(ctrl);
}
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -765,7 +765,7 @@ int pcie_init_notification(struct contro
return 0;
}
-static void pcie_shutdown_notification(struct controller *ctrl)
+void pcie_shutdown_notification(struct controller *ctrl)
{
if (ctrl->notification_enabled) {
pcie_disable_notification(ctrl);
@@ -800,7 +800,7 @@ abort:
static void pcie_cleanup_slot(struct controller *ctrl)
{
struct slot *slot = ctrl->slot;
- cancel_delayed_work(&slot->work);
+
destroy_workqueue(slot->wq);
kfree(slot);
}
@@ -893,7 +893,6 @@ abort:
void pciehp_release_ctrl(struct controller *ctrl)
{
- pcie_shutdown_notification(ctrl);
pcie_cleanup_slot(ctrl);
kfree(ctrl);
}
next prev parent reply other threads:[~2018-08-23 7:56 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-23 7:56 [PATCH 4.18 00/22] 4.18.5-stable review Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 01/22] EDAC: Add missing MEM_LRDDR4 entry in edac_mem_types[] Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 02/22] pty: fix O_CLOEXEC for TIOCGPTPEER Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 03/22] mm: Allow non-direct-map arguments to free_reserved_area() Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 04/22] x86/mm/init: Pass unconverted symbol addresses to free_init_pages() Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 05/22] x86/mm/init: Add helper for freeing kernel image pages Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 06/22] x86/mm/init: Remove freed kernel image areas from alias mapping Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 07/22] powerpc64s: Show ori31 availability in spectre_v1 sysfs file not v2 Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 08/22] ext4: fix spectre gadget in ext4_mb_regular_allocator() Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 09/22] drm/i915/kvmgt: Fix potential Spectre v1 Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 10/22] drm/amdgpu/pm: " Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 14/22] PCI / ACPI / PM: Resume all bridges on suspend-to-RAM Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 15/22] PCI: hotplug: Dont leak pci_slot on registration failure Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 16/22] PCI: aardvark: Size bridges before resources allocation Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 17/22] PCI: Skip MPS logic for Virtual Functions (VFs) Greg Kroah-Hartman
2018-08-23 7:56 ` Greg Kroah-Hartman [this message]
2018-08-23 7:56 ` [PATCH 4.18 19/22] PCI: pciehp: Fix unprotected list iteration in IRQ handler Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 20/22] i2c: core: ACPI: Properly set status byte to 0 for multi-byte writes Greg Kroah-Hartman
2018-08-23 7:56 ` [PATCH 4.18 22/22] reiserfs: fix broken xattr handling (heap corruption, bad retval) Greg Kroah-Hartman
2018-08-23 19:20 ` [PATCH 4.18 00/22] 4.18.5-stable review Shuah Khan
2018-08-23 20:34 ` Greg Kroah-Hartman
2018-08-23 20:12 ` Guenter Roeck
2018-08-23 20:52 ` Greg Kroah-Hartman
2018-08-24 5:07 ` Naresh Kamboju
2018-08-24 6:18 ` Greg Kroah-Hartman
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=20180823074800.339789967@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=bhelgaas@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lukas@wunner.de \
--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;
as well as URLs for NNTP newsgroup(s).