summaryrefslogtreecommitdiffhomepage
path: root/device.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-12-04 20:16:49 +0100
committerFelix Fietkau <nbd@openwrt.org>2011-12-04 20:16:52 +0100
commita6baf95e700f1abe8dafe71f5f8722baea6b6ac2 (patch)
tree900da16fa2c9c762759d3ed6745d1e9b3b640342 /device.c
parent8d18904bc241fef09ad6e8b7c2e1f93a4b4bb082 (diff)
fix use-after-free on device free codepath due to recursion issues, and fix dev->parent refcounting issues
Diffstat (limited to 'device.c')
-rw-r--r--device.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/device.c b/device.c
index b2db291..91cb37a 100644
--- a/device.c
+++ b/device.c
@@ -68,12 +68,17 @@ static int set_device_state(struct device *dev, bool state)
static int
simple_device_set_state(struct device *dev, bool state)
{
+ struct device *pdev;
int ret = 0;
- if (state && !dev->parent.dev)
- dev->parent.dev = system_if_get_parent(dev);
+ pdev = dev->parent.dev;
+ if (state && !pdev) {
+ pdev = system_if_get_parent(dev);
+ if (pdev)
+ device_add_user(&dev->parent, pdev);
+ }
- if (dev->parent.dev) {
+ if (pdev) {
if (state)
ret = device_claim(&dev->parent);
else
@@ -425,6 +430,14 @@ void device_add_user(struct device_user *dep, struct device *dev)
}
}
+void
+device_free(struct device *dev)
+{
+ __devlock++;
+ dev->type->free(dev);
+ __devlock--;
+}
+
static void
__device_free_unused(struct device *dev)
{