Module: xenomai-2.6 Branch: master Commit: 0f1ae8401ceaa8af387062b1e126a66e0c7c9c1f URL: http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=0f1ae8401ceaa8af387062b1e126a66e0c7c9c1f
Author: Philippe Gerum <r...@xenomai.org> Date: Fri Apr 11 15:16:02 2014 +0200 analogy/device: sanitize device release handler The main 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 Signed-off-by: Andreas Glatz <andi.gl...@gmail.com> More fixups are included to sanitize this handler a bit further. Signed-off-by: Philippe Gerum <r...@xenomai.org> --- ksrc/drivers/analogy/device.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/ksrc/drivers/analogy/device.c b/ksrc/drivers/analogy/device.c index b93ae72..60b2977 100644 --- a/ksrc/drivers/analogy/device.c +++ b/ksrc/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