Module: xenomai-forge Branch: next Commit: b6c88a9fe1c2f2bedc06bfc44ac8a2fbe1875e82 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=b6c88a9fe1c2f2bedc06bfc44ac8a2fbe1875e82
Author: Philippe Gerum <r...@xenomai.org> Date: Mon Aug 11 20:23:45 2014 +0200 cobalt/rtdm: drop spurious validation check in rtdm_dev_unregister() Performing a validation lookup for the device to remove only covers the case when a driver calls rtdm_dev_unregister() with an "almost valid", but still unregistered device structure. Any other case would cause the lookup to be started on a device name living on potentially stale, uninit or otherwise random memory, corresponding to an invalid device structure. However, passing a half-baked/forged rtdm_device structure only with correct name data and magic word would lead to the successful removal of a valid but distinct device structure registered earlier, which would definitely make no sense. Drop this check, and hold a reference directly on the device structure received. RTDM already (rightfully) assumes in all other services that object descriptors received as arguments shall be valid. --- kernel/cobalt/rtdm/device.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c index 62003de..547c8f8 100644 --- a/kernel/cobalt/rtdm/device.c +++ b/kernel/cobalt/rtdm/device.c @@ -306,16 +306,13 @@ EXPORT_SYMBOL_GPL(rtdm_dev_register); * * @return 0 is returned upon success. Otherwise: * - * - -ENODEV is returned if the device was not registered. - * - * - -EAGAIN is returned if the device is busy with open instances and 0 has - * been passed for @a poll_delay. + * - -EAGAIN is returned if the device is busy with open instances and + * 0 has been passed for @a poll_delay. * * @coretags{secondary-only} */ int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay) { - struct rtdm_device *reg_dev; unsigned long warned = 0; xnhandle_t handle = 0; spl_t s; @@ -323,31 +320,25 @@ int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay) if (!rtdm_initialised) return -ENOSYS; - if ((device->device_flags & RTDM_DEVICE_TYPE_MASK) == RTDM_NAMED_DEVICE) - reg_dev = get_named_device(device->device_name); - else - reg_dev = get_protocol_device(device->protocol_family, - device->socket_type); - if (!reg_dev) - return -ENODEV; + rtdm_reference_device(device); trace_cobalt_device_unregister(device, poll_delay); down(&nrt_dev_lock); xnlock_get_irqsave(&rt_dev_lock, s); - while (atomic_read(®_dev->reserved.refcount) > 1) { + while (atomic_read(&device->reserved.refcount) > 1) { xnlock_put_irqrestore(&rt_dev_lock, s); up(&nrt_dev_lock); if (!poll_delay) { - rtdm_dereference_device(reg_dev); + rtdm_dereference_device(device); return -EAGAIN; } if (!__test_and_set_bit(0, &warned)) printk(XENO_WARN "RTDM device %s still in use - waiting for" - " release...\n", reg_dev->device_name); + " release...\n", device->device_name); msleep(poll_delay); down(&nrt_dev_lock); xnlock_get_irqsave(&rt_dev_lock, s); @@ -355,10 +346,10 @@ int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay) if ((device->device_flags & RTDM_DEVICE_TYPE_MASK) == RTDM_NAMED_DEVICE) { - handle = reg_dev->reserved.handle; - list_del(®_dev->reserved.entry); + handle = device->reserved.handle; + list_del(&device->reserved.entry); } else - xnid_remove(&rtdm_protocol_devices, ®_dev->reserved.id); + xnid_remove(&rtdm_protocol_devices, &device->reserved.id); xnlock_put_irqrestore(&rt_dev_lock, s); @@ -369,7 +360,7 @@ int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay) up(&nrt_dev_lock); - if (reg_dev->reserved.exclusive_context) + if (device->reserved.exclusive_context) kfree(device->reserved.exclusive_context); return 0; _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git