fix use-after-free on device free codepath due to recursion issues, and fix dev-...
authorFelix Fietkau <nbd@openwrt.org>
Sun, 4 Dec 2011 19:16:49 +0000 (20:16 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 4 Dec 2011 19:16:52 +0000 (20:16 +0100)
device.c
device.h

index b2db29168dfd439166748e1de271e54547b6a827..91cb37a615a8c94c2db9ee002745f1f862206a57 100644 (file)
--- 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)
 {
index 0d9e6f4e3420fa638be6a7441cf5d82f4ef6c07d..c0b112dddebfd53190766a06d60d7d45b488165e 100644 (file)
--- 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);