diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-10-19 03:20:09 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2011-10-19 03:20:09 +0200 |
commit | d16871c7a55370174eb672edee24feade74cd37e (patch) | |
tree | 39995e27e86f9efbf101a8b9f5a23e7d9821bae8 /ubus.c | |
parent | ccca61c97d460d73f29750abdf38cea20ac440f3 (diff) |
rework device hotplug handling some more, add device_lock/device_unlock to prevent use-after-free bugs
Diffstat (limited to 'ubus.c')
-rw-r--r-- | ubus.c | 29 |
1 files changed, 17 insertions, 12 deletions
@@ -284,14 +284,18 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj, return UBUS_STATUS_INVALID_ARGUMENT; devname = blobmsg_data(tb[DEV_NAME]); - dev = iface->main_dev.dev; - if (iface->hotplug_dev && dev && !add) { - if (strcmp(dev->ifname, devname) != 0) - return UBUS_STATUS_INVALID_ARGUMENT; - } - if (iface->hotplug_dev) { - if (iface->main_dev.dev) { + device_lock(); + + if (iface->main_dev.hotplug) { + dev = iface->main_dev.dev; + + if (dev) { + if (!add && strcmp(dev->ifname, devname) != 0) { + ret = UBUS_STATUS_INVALID_ARGUMENT; + goto out; + } + interface_set_available(iface, false); device_remove_user(&iface->main_dev); } @@ -299,13 +303,15 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj, main_dev = iface->main_dev.dev; dev = device_get(blobmsg_data(tb[DEV_NAME]), add); - if (!dev) - return UBUS_STATUS_NOT_FOUND; + if (!dev && (main_dev || add)) { + ret = UBUS_STATUS_NOT_FOUND; + goto out; + } if (!main_dev) { if (add) { device_add_user(&iface->main_dev, dev); - iface->hotplug_dev = true; + iface->main_dev.hotplug = true; } ret = 0; goto out; @@ -328,8 +334,7 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj, } out: - if (add) - device_free_unused(dev); + device_unlock(); return ret; } |