FAILED: patch "[PATCH] PCI: hv: Fix a use-after-free bug in hv_eject_device_work()" failed to apply to 4.9-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 4df591b20b80cb77920953812d894db259d85bd7 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <[email protected]>
Date: Fri, 21 Jun 2019 23:45:23 +0000
Subject: [PATCH] PCI: hv: Fix a use-after-free bug in hv_eject_device_work()
Fix a use-after-free in hv_eject_device_work().
drivers/pci/controller/pci-hyperv.c +9 -6
@@ -1875,6 +1875,7 @@ static void hv_pci_devices_present(struct hv_pcibus_device *hbus,static void hv_eject_device_work (struct work_struct *work) {struct pci_eject_response *ejct_pkt; +struct hv_pcibus_device *hbus;struct hv_pci_dev *hpdev;struct pci_dev *pdev;unsigned long flags;
@@ -1885,6 +1886,7 @@ static void hv_eject_device_work(struct work_struct *work) } ctxt; hpdev = container_of(work, struct hv_pci_dev, wrk); + hbus = hpdev->hbus;WARN_ON (hpdev->state != hv_pcichild_ejecting);
@@ -1895,8 +1897,7 @@ static void hv_eject_device_work(struct work_struct *work)* because hbus->pci_bus may not exist yet. */ wslot =wslot_to_devfn (hpdev->desc.win_slot.slot); - pdev =pci_get_domain_bus_and_slot (hpdev->hbus->sysdata.domain,0 , - wslot); + pdev =pci_get_domain_bus_and_slot (hbus->sysdata.domain,0 , wslot);if (pdev) {pci_lock_rescan_remove ();pci_stop_and_remove_bus_device (pdev);
@@ -1904,9 +1905,9 @@ static void hv_eject_device_work(struct work_struct *work)pci_unlock_rescan_remove (); } -spin_lock_irqsave (&hpdev->hbus->device_list_lock, flags); +spin_lock_irqsave (&hbus->device_list_lock, flags);list_del (&hpdev->list_entry); -spin_unlock_irqrestore (&hpdev->hbus->device_list_lock, flags); +spin_unlock_irqrestore (&hbus->device_list_lock, flags);if (hpdev->pci_slot)pci_destroy_slot (hpdev->pci_slot);
@@ -1915,7 +1916,7 @@ static void hv_eject_device_work(struct work_struct *work) ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message; ejct_pkt->message_type.type =PCI_EJECTION_COMPLETE ; ejct_pkt->wslot.slot = hpdev->desc.win_slot.slot; -vmbus_sendpacket (hpdev->hbus->hdev->channel, ejct_pkt, +vmbus_sendpacket (hbus->hdev->channel, ejct_pkt,sizeof (*ejct_pkt), (unsigned long )&ctxt.pkt,VM_PKT_DATA_INBAND ,0 );
@@ -1924,7 +1925,9 @@ static void hv_eject_device_work(struct work_struct *work)/* For the two refs got in new_pcichild_device() */ put_pcichild (hpdev);put_pcichild (hpdev); -put_hvpcibus (hpdev->hbus); +/* hpdev has been freed. Do not use it any more. */ + +put_hvpcibus (hbus); }/**
Quoted 18 lines
From: [email protected] <[email protected]>
Sent: Tuesday, July 23, 2019 4:59 AM
To: Dexuan Cui <[email protected]>; [email protected]; Michael Kelley <[email protected]>
Cc: [email protected]
Subject: FAILED: patch "[PATCH] PCI: hv: Fix a use-after-free bug inhv_eject_device_work()" failed to apply to 4.9-stable treeThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.thanks,
greg k-h
Quoted 7 lines
------------------ original commit in Linus's tree ------------------
From
4df591b20b80cb77920953812d894db259d85bd7Mon Sep 17 00:00:00 2001
From: Dexuan Cui <[email protected]>
Date: Fri, 21 Jun 2019 23:45:23 +0000
Subject: [PATCH] PCI: hv: Fix a use-after-free bug inhv_eject_device_work()
Hi,
To apply this patch to v4.9.186, we need to cherry-pick another patch first:e74d2ebdda33 ("PCI: hv: Delete the device earlier from hbus->children for hot-remove")
Then I backported this commit (4df591b20)
Please see the two attachments for the two patches. They can be cleanly applied to v4.9.186.
Thanks,
-- Dexuan
From 70913034cdcf061020573d64d4890c3781c63b6b Mon Sep 17 00:00:00 2001
From: Dexuan Cui <[email protected]>
Date: Thu, 10 Nov 2016 07:19:52 +0000
Subject: [PATCH for-4.9.186 1/2] PCI: hv: Delete the device earlier from
hbus->children for hot-remove
Reply-To: [email protected]
[ Upstream commit e74d2ebdda33b3bdd1826b5b92e9aa45bdf92bb3 ]
After we send a PCI_EJECTION_COMPLETE message to the host, the host will immediately send us a PCI_BUS_RELATIONS message with relations->device_count == 0, so pci_devices_present_work(), running on another thread, can find the being-ejected device, mark the hpdev->reported_missing to true, and run list_move_tail()/list_del() for the device -- this races hv_eject_device_work() -> list_del().
Move the list_del() in hv_eject_device_work() to an earlier place, i.e., before we send PCI_EJECTION_COMPLETE, so later the pci_devices_present_work() can't see the device.
--- drivers/pci/host/pci-hyperv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/pci/host/pci-hyperv.c +4 -4
@@ -1607,6 +1607,10 @@ static void hv_eject_device_work(struct work_struct *work)pci_unlock_rescan_remove (); } +spin_lock_irqsave (&hpdev->hbus->device_list_lock, flags); +list_del (&hpdev->list_entry); +spin_unlock_irqrestore (&hpdev->hbus->device_list_lock, flags); +memset (&ctxt,0 ,sizeof (ctxt)); ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message; ejct_pkt->message_type.type =PCI_EJECTION_COMPLETE ;
@@ -1615,10 +1619,6 @@ static void hv_eject_device_work(struct work_struct *work)sizeof (*ejct_pkt), (unsigned long )&ctxt.pkt, VM_PKT_DATA_INBAND, 0); -spin_lock_irqsave (&hpdev->hbus->device_list_lock, flags); -list_del (&hpdev->list_entry); -spin_unlock_irqrestore (&hpdev->hbus->device_list_lock, flags); -put_pcichild (hpdev, hv_pcidev_ref_childlist);put_pcichild (hpdev, hv_pcidev_ref_initial);put_pcichild (hpdev, hv_pcidev_ref_pnp);
Signature · 1 line
1.8.3.1
From ec241858c53dd7fdc98a8f4ee4719bf64e0677f8 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <[email protected]>
Date: Tue, 23 Jul 2019 17:30:41 -0700
Subject: [PATCH for-4.9.186 2/2] PCI: hv: Fix a use-after-free bug in
hv_eject_device_work()
Reply-To: [email protected]
[ Upstream commit 4df591b20b80cb77920953812d894db259d85bd7 ]
Fix a use-after-free in hv_eject_device_work().
--- drivers/pci/host/pci-hyperv.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/pci/host/pci-hyperv.c +9 -6
@@ -1575,6 +1575,7 @@ static void hv_pci_devices_present(struct hv_pcibus_device *hbus,static void hv_eject_device_work (struct work_struct *work) {struct pci_eject_response *ejct_pkt; +struct hv_pcibus_device *hbus;struct hv_pci_dev *hpdev;struct pci_dev *pdev;unsigned long flags;
@@ -1585,6 +1586,7 @@ static void hv_eject_device_work(struct work_struct *work) } ctxt; hpdev = container_of(work, struct hv_pci_dev, wrk); + hbus = hpdev->hbus;if (hpdev->state != hv_pcichild_ejecting) {put_pcichild (hpdev, hv_pcidev_ref_pnp);
@@ -1598,8 +1600,7 @@ static void hv_eject_device_work(struct work_struct *work)* because hbus->pci_bus may not exist yet. */ wslot =wslot_to_devfn (hpdev->desc.win_slot.slot); - pdev =pci_get_domain_bus_and_slot (hpdev->hbus->sysdata.domain,0 , - wslot); + pdev =pci_get_domain_bus_and_slot (hbus->sysdata.domain,0 , wslot);if (pdev) {pci_lock_rescan_remove ();pci_stop_and_remove_bus_device (pdev);
@@ -1607,22 +1608,24 @@ static void hv_eject_device_work(struct work_struct *work)pci_unlock_rescan_remove (); } -spin_lock_irqsave (&hpdev->hbus->device_list_lock, flags); +spin_lock_irqsave (&hbus->device_list_lock, flags);list_del (&hpdev->list_entry); -spin_unlock_irqrestore (&hpdev->hbus->device_list_lock, flags); +spin_unlock_irqrestore (&hbus->device_list_lock, flags);memset (&ctxt,0 ,sizeof (ctxt)); ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message; ejct_pkt->message_type.type =PCI_EJECTION_COMPLETE ; ejct_pkt->wslot.slot = hpdev->desc.win_slot.slot; -vmbus_sendpacket (hpdev->hbus->hdev->channel, ejct_pkt, +vmbus_sendpacket (hbus->hdev->channel, ejct_pkt,sizeof (*ejct_pkt), (unsigned long )&ctxt.pkt,VM_PKT_DATA_INBAND ,0 );put_pcichild (hpdev, hv_pcidev_ref_childlist);put_pcichild (hpdev, hv_pcidev_ref_initial);put_pcichild (hpdev, hv_pcidev_ref_pnp); -put_hvpcibus (hpdev->hbus); + +/* hpdev has been freed. Do not use it any more. */ +put_hvpcibus (hbus); }/**
Signature · 1 line
1.8.3.1
[email protected]
maintainerQuoted 26 lines · Dexuan Cui
Quoted 18 lines
From: [email protected] <[email protected]>
Sent: Tuesday, July 23, 2019 4:59 AM
To: Dexuan Cui <[email protected]>; [email protected]; Michael Kelley <[email protected]>
Cc: [email protected]
Subject: FAILED: patch "[PATCH] PCI: hv: Fix a use-after-free bug inhv_eject_device_work()" failed to apply to 4.9-stable treeThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.thanks,
greg k-h
Quoted 7 lines
------------------ original commit in Linus's tree ------------------
From
4df591b20b80cb77920953812d894db259d85bd7Mon Sep 17 00:00:00 2001
From: Dexuan Cui <[email protected]>
Date: Fri, 21 Jun 2019 23:45:23 +0000
Subject: [PATCH] PCI: hv: Fix a use-after-free bug inhv_eject_device_work()
Quoted 8 lines
Hi,
To apply this patch to v4.9.186, we need to cherry-pick another patch first:e74d2ebdda33("PCI: hv: Delete the device earlier fromhbus->childrenfor hot-remove")Then I backported this commit (
4df591b20)Please see the two attachments for the two patches. They can be cleanly applied to v4.9.186.
Now queued up, thanks.
greg k-h