Module: xenomai-forge
Branch: next
Commit: 0a6d1fc0e758407e307e9f0107c2bb416f816553
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=0a6d1fc0e758407e307e9f0107c2bb416f816553

Author: Philippe Gerum <r...@xenomai.org>
Date:   Fri Sep 19 16:38:25 2014 +0200

cobalt/rtdm: sanitize handling of exclusive context

---

 include/cobalt/kernel/rtdm/driver.h |    1 -
 kernel/cobalt/posix/io.c            |   11 ++++----
 kernel/cobalt/rtdm/core.c           |   49 +++++++++++++----------------------
 kernel/cobalt/rtdm/device.c         |   19 --------------
 4 files changed, 23 insertions(+), 57 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 9db9e1b..5b566f2 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -346,7 +346,6 @@ struct rtdm_device {
                dev_t rdev;
                struct device *kdev;
                atomic_t refcount;
-               struct rtdm_dev_context *exclusive_context;
                struct rtdm_fd_ops ops;
                wait_queue_head_t putwq;
        };
diff --git a/kernel/cobalt/posix/io.c b/kernel/cobalt/posix/io.c
index 8038bd3..be58bd6 100644
--- a/kernel/cobalt/posix/io.c
+++ b/kernel/cobalt/posix/io.c
@@ -50,13 +50,15 @@ COBALT_SYSCALL(open, lostage,
        device = __rtdm_get_namedev(filename->name);
        if (device == NULL) {
                ret = -ENODEV;
-               goto fail_lookup;
+               goto fail;
        }
+       /* __rt_dev_open() will revalidate. */
+       __rtdm_put_device(device);
 
        ufd = get_unused_fd_flags(oflag);
        if (ufd < 0) {
                ret = ufd;
-               goto fail_ufd;
+               goto fail;
        }
 
        filp = filp_open(filename->name, oflag, 0);
@@ -70,7 +72,6 @@ COBALT_SYSCALL(open, lostage,
        if (ret < 0)
                goto fail_devopen;
 
-       __rtdm_put_device(device);
        fd_install(ufd, filp);
        putname(filename);
 
@@ -79,9 +80,7 @@ fail_devopen:
        filp_close(filp, current->files);
 fail_fopen:
        put_unused_fd(ufd);
-fail_ufd:
-       __rtdm_put_device(device);
-fail_lookup:
+fail:
        putname(filename);
 
        return ret;
diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c
index 2baf664..5e05b30 100644
--- a/kernel/cobalt/rtdm/core.c
+++ b/kernel/cobalt/rtdm/core.c
@@ -41,12 +41,8 @@ DEFINE_XNLOCK(rt_fildes_lock);
 static void cleanup_instance(struct rtdm_device *device,
                             struct rtdm_dev_context *context)
 {
-       if (context) {
-               if (device->exclusive_context)
-                       context->device = NULL;
-               else
-                       kfree(context);
-       }
+       if (context)
+               kfree(context);
 
        __rtdm_put_device(device);
 }
@@ -80,9 +76,10 @@ static int create_instance(struct xnsys_ppd *p, int fd,
                           struct rtdm_device *device,
                           struct rtdm_dev_context **context_ptr)
 {
+       struct rtdm_device_class *class = device->class;
        struct rtdm_dev_context *context;
        spl_t s;
-       int err;
+       int ret;
 
        /*
         * Reset to NULL so that we can always use cleanup_files/instance to
@@ -105,34 +102,24 @@ static int create_instance(struct xnsys_ppd *p, int fd,
                xnlock_put_irqrestore(&rt_fildes_lock, s);
        }
 
-       context = device->exclusive_context;
-       if (context) {
-               xnlock_get_irqsave(&rt_dev_lock, s);
-
-               if (unlikely(context->device != NULL)) {
-                       xnlock_put_irqrestore(&rt_dev_lock, s);
-                       err = -EBUSY;
-                       goto fail;
-               }
-
-               context->device = device;
-
-               xnlock_put_irqrestore(&rt_dev_lock, s);
-       } else {
-               context = kmalloc(sizeof(struct rtdm_dev_context) +
-                               device->class->context_size, GFP_KERNEL);
-               if (unlikely(context == NULL)) {
-                       err = -ENOMEM;
-                       goto fail;
-               }
+       if ((class->device_flags & RTDM_EXCLUSIVE) != 0 &&
+           atomic_read(&device->refcount) > 1) {
+               ret = -EBUSY;
+               goto fail;
+       }
 
-               context->device = device;
+       context = kmalloc(sizeof(struct rtdm_dev_context) +
+                         class->context_size, GFP_KERNEL);
+       if (unlikely(context == NULL)) {
+               ret = -ENOMEM;
+               goto fail;
        }
 
+       context->device = device;
        *context_ptr = context;
 
-       err = rtdm_fd_enter(p, &context->fd, fd, RTDM_FD_MAGIC, &device->ops);
-       if (err < 0)
+       ret = rtdm_fd_enter(p, &context->fd, fd, RTDM_FD_MAGIC, &device->ops);
+       if (ret < 0)
                goto fail;
 
        return fd;
@@ -144,7 +131,7 @@ fail:
                xnlock_put_irqrestore(&rt_fildes_lock, s);
        }
 
-       return err;
+       return ret;
 }
 
 int __rt_dev_open(struct xnsys_ppd *p, int ufd, const char *path, int oflag)
diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c
index 69de887..0432a7b 100644
--- a/kernel/cobalt/rtdm/device.c
+++ b/kernel/cobalt/rtdm/device.c
@@ -292,7 +292,6 @@ int rtdm_dev_register(struct rtdm_device *device)
        down(&nrt_dev_lock);
 
        device->name = NULL;
-       device->exclusive_context = NULL;
        class = device->class;
        pos = atomic_read(&class->refcount);
        ret = register_device_class(class);
@@ -311,18 +310,6 @@ int rtdm_dev_register(struct rtdm_device *device)
        device->ops.close = __rt_dev_close; /* Interpose on driver's handler. */
        atomic_set(&device->refcount, 0);
 
-       if (class->device_flags & RTDM_EXCLUSIVE) {
-               device->exclusive_context =
-                       kmalloc(sizeof(struct rtdm_dev_context) +
-                               class->context_size, GFP_KERNEL);
-               if (device->exclusive_context == NULL) {
-                       ret = -ENOMEM;
-                       goto fail;
-               }
-               /* mark exclusive context as unused */
-               device->exclusive_context->device = NULL;
-       }
-
        if (class->device_flags & RTDM_FIXED_MINOR) {
                minor = device->minor;
                if (minor < 0 || minor >= class->device_count) {
@@ -400,9 +387,6 @@ fail:
        if (device->name)
                kfree(device->name);
 
-       if (device->exclusive_context)
-               kfree(device->exclusive_context);
-
        return ret;
 }
 EXPORT_SYMBOL_GPL(rtdm_dev_register);
@@ -454,9 +438,6 @@ void rtdm_dev_unregister(struct rtdm_device *device)
 
        up(&nrt_dev_lock);
 
-       if (device->exclusive_context)
-               kfree(device->exclusive_context);
-
        kfree(device->name);
 }
 EXPORT_SYMBOL_GPL(rtdm_dev_unregister);


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to