From a6baf95e700f1abe8dafe71f5f8722baea6b6ac2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 4 Dec 2011 20:16:49 +0100 Subject: [PATCH] fix use-after-free on device free codepath due to recursion issues, and fix dev->parent refcounting issues --- device.c | 19 ++++++++++++++++--- device.h | 7 +------ 2 files changed, 17 insertions(+), 9 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) { diff --git a/device.h b/device.h index 0d9e6f4..c0b112d 100644 --- a/device.h +++ b/device.h @@ -148,12 +148,7 @@ void device_release(struct device_user *dep); int device_check_state(struct device *dev); void device_dump_status(struct blob_buf *b, struct device *dev); -static inline void -device_free(struct device *dev) -{ - dev->type->free(dev); -} - +void device_free(struct device *dev); void device_free_unused(struct device *dev); struct device *get_vlan_device_chain(const char *ifname, bool create); -- 2.25.1