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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Fri Apr 11 15:16:02 2014 +0200

analogy/device: sanitize device release handler

This change fixes a crash when a zero-sized private area is specified
for the driver:
http://www.xenomai.org/pipermail/xenomai/2014-April/030628.html

More fixups are included to sanitize this handler a bit further.

---

 kernel/drivers/analogy/device.c |   27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/kernel/drivers/analogy/device.c b/kernel/drivers/analogy/device.c
index b93ae72..60b2977 100644
--- a/kernel/drivers/analogy/device.c
+++ b/kernel/drivers/analogy/device.c
@@ -278,17 +278,15 @@ int a4l_assign_driver(a4l_cxt_t * cxt,
        a4l_dev_t *dev = a4l_get_dev(cxt);
 
        dev->driver = drv;
+       INIT_LIST_HEAD(&dev->subdvsq);
 
        if (drv->privdata_size == 0)
                __a4l_dbg(1, core_dbg,
                          "a4l_assign_driver: warning! "
                          "the field priv will not be usable\n");
        else {
-
-               INIT_LIST_HEAD(&dev->subdvsq);
-
                dev->priv = rtdm_malloc(drv->privdata_size);
-               if (dev->priv == NULL && drv->privdata_size != 0) {
+               if (dev->priv == NULL) {
                        __a4l_err("a4l_assign_driver: "
                                  "call(alloc) failed\n");
                        ret = -ENOMEM;
@@ -325,27 +323,26 @@ out_assign_driver:
 
 int a4l_release_driver(a4l_cxt_t * cxt)
 {
-       int ret = 0;
        a4l_dev_t *dev = a4l_get_dev(cxt);
+       a4l_subd_t *subd, *tmp;
+       int ret = 0;
 
        if ((ret = dev->driver->detach(dev)) != 0)
                goto out_release_driver;
 
-       /* Decrease module's count
-          so as to allow module unloading */
        module_put(dev->driver->owner);
 
        /* In case, the driver developer did not free the subdevices */
-       while (&dev->subdvsq != dev->subdvsq.next) {
-               struct list_head *this = dev->subdvsq.next;
-               a4l_subd_t *tmp = list_entry(this, a4l_subd_t, list);
-
-               list_del(this);
-               rtdm_free(tmp);
-       }
+       if (!list_empty(&dev->subdvsq))
+               list_for_each_entry_safe(subd, tmp, &dev->subdvsq, list) {
+                       list_del(&subd->list);
+                       rtdm_free(subd);
+               }
 
        /* Free the private field */
-       rtdm_free(dev->priv);
+       if (dev->priv)
+               rtdm_free(dev->priv);
+
        dev->driver = NULL;
 
 out_release_driver:


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

Reply via email to