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(&reg_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(&reg_dev->reserved.entry);
+               handle = device->reserved.handle;
+               list_del(&device->reserved.entry);
        } else
-               xnid_remove(&rtdm_protocol_devices, &reg_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

Reply via email to