All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] kernel/resource.c: invalidate parent when freed resource has childs
@ 2019-08-08 15:40 Schmid, Carsten
  2019-08-09 13:50 ` Resend " Schmid, Carsten
  0 siblings, 1 reply; 17+ messages in thread
From: Schmid, Carsten @ 2019-08-08 15:40 UTC (permalink / raw)
  To: linux-kernel

When a resource is freed and has children, the childrens are
left without any hint that their parent is no more valid.
This caused at least one use-after-free in the xhci-hcd using
ext-caps driver when platform code released platform devices.

Fix this by setting child's parent to zero and warn.

Signed-off-by: Carsten Schmid <carsten_schmid@mentor.com>
---
Rationale:
When hunting for the root cause of a crash on a 4.14.86 kernel, i
have found the root cause and checked it being still present
upstream. Our case:
Having xhci-hcd and intel_xhci_usb_sw active we can see in
/proc/meminfo: (exceirpt)
  b3c00000-b3c0ffff : 0000:00:15.0
    b3c00000-b3c0ffff : xhci-hcd
      b3c08070-b3c0846f : intel_xhci_usb_sw
intel_xhci_usb_sw being a child of xhci-hcd.

Doing an unbind command
echo 0000:00:15.0 > /sys/bus/pci/drivers/xhci_hcd/unbind
leads to xhci-hcd being freed in __release_region.
The intel_xhci_usb_sw resource is accessed in platform code
in platform_device_del with
		for (i = 0; i < pdev->num_resources; i++) {
			struct resource *r = &pdev->resource[i];
			if (r->parent)
				release_resource(r);
		}
as the resource's parent has not been updated, the release_resource
uses the parent:
	p = &old->parent->child;
which is now invalid.
Fix this by marking the parent invalid in the child and give a warning
in dmesg.
---
 kernel/resource.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/kernel/resource.c b/kernel/resource.c
index 158f04ec1d4f..95340cb0b1c2 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -1200,6 +1200,15 @@ void __release_region(struct resource *parent, resource_size_t start,
 			write_unlock(&resource_lock);
 			if (res->flags & IORESOURCE_MUXED)
 				wake_up(&muxed_resource_wait);
+
+			write_lock(&resource_lock);
+			if (res->child) {
+				printk(KERN_WARNING "__release_region: %s has child %s,"
+						"invalidating childs parent\n",
+						res->name, res->child->name);
+				res->child->parent = NULL;
+			}
+			write_unlock(&resource_lock);
 			free_resource(res);
 			return;
 		}
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2019-08-16 10:18 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-08 15:40 [PATCH] kernel/resource.c: invalidate parent when freed resource has childs Schmid, Carsten
2019-08-09 13:50 ` Resend " Schmid, Carsten
2019-08-09 16:59   ` Dan Williams
2019-08-09 18:37   ` Joe Perches
2019-08-09 18:54     ` [PATCH] kernel/resource.c: Convert printks to pr_<level> Joe Perches
2019-08-09 20:09   ` Resend [PATCH] kernel/resource.c: invalidate parent when freed resource has childs Linus Torvalds
2019-08-09 22:38   ` Wei Yang
2019-08-09 22:45     ` Linus Torvalds
2019-08-10  0:44       ` Wei Yang
2019-08-12  8:39         ` AW: " Schmid, Carsten
2019-08-13  8:09       ` Schmid, Carsten
2019-08-14 14:48       ` [PATCH v2] " Schmid, Carsten
2019-08-14 16:29         ` Wei Yang
2019-08-15  8:18           ` AW: " Schmid, Carsten
2019-08-15 13:03             ` Wei Yang
2019-08-15 13:17               ` AW: " Schmid, Carsten
2019-08-16 10:18                 ` [PATCH] kernel/resource.c: warn if released region has children Schmid, Carsten

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.