From 0fbf116d120a2dc5d808204c7d86ad35f7d7846f Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Wed, 27 Sep 2006 23:38:08 +0200 Subject: Driver core: plug device probe memory leak Make sure data is freed if the kthread fails to start. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/dd.c b/drivers/base/dd.c index b5f43c3e44f..ef7db6939cb 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -178,7 +178,7 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) probe_task = kthread_run(really_probe, data, "probe-%s", dev->bus_id); if (IS_ERR(probe_task)) - ret = PTR_ERR(probe_task); + ret = really_probe(data); } else ret = really_probe(data); -- cgit v1.2.3 From 310a922d4307ed38b37982a6f93b11fdf3b8dcb1 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sat, 23 Sep 2006 23:35:04 -0600 Subject: Fix dev_printk() is now GPL-only Make dev_printk usable from non-GPL modules again dev_printk now calls dev_driver_string. We want even proprietary modules to be calling dev_printk, so the export of dev_driver_string needs to be non-GPL-only. Signed-off-by: Matthew Wilcox Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/core.c b/drivers/base/core.c index b224bb43ff6..aee3743bd4a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -44,7 +44,7 @@ const char *dev_driver_string(struct device *dev) return dev->driver ? dev->driver->name : (dev->bus ? dev->bus->name : ""); } -EXPORT_SYMBOL_GPL(dev_driver_string); +EXPORT_SYMBOL(dev_driver_string); #define to_dev(obj) container_of(obj, struct device, kobj) #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) -- cgit v1.2.3 From f0e1761ac528e9d28f3ba06bd268ec41fe872ac8 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 22 Sep 2006 11:37:00 +0200 Subject: driver core fixes: sysfs_create_link() retval check in class.c Check for return value of sysfs_create_link() in class_device_add(). Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/class.c b/drivers/base/class.c index b32b77ff2dc..0ff267a248d 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -562,7 +562,10 @@ int class_device_add(struct class_device *class_dev) goto out2; /* add the needed attributes to this device */ - sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem"); + error = sysfs_create_link(&class_dev->kobj, + &parent_class->subsys.kset.kobj, "subsystem"); + if (error) + goto out3; class_dev->uevent_attr.attr.name = "uevent"; class_dev->uevent_attr.attr.mode = S_IWUSR; class_dev->uevent_attr.attr.owner = parent_class->owner; -- cgit v1.2.3 From 1bb6881acae1c4f11a6e86f04df32ba45e95031d Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 22 Sep 2006 11:37:04 +0200 Subject: driver core fixes: bus_add_attrs() retval check Check return value of bus_add_attrs() in bus_register(). Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 12173d16bea..b90f6e6f644 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -732,11 +732,15 @@ int bus_register(struct bus_type * bus) klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); klist_init(&bus->klist_drivers, NULL, NULL); - bus_add_attrs(bus); + retval = bus_add_attrs(bus); + if (retval) + goto bus_attrs_fail; pr_debug("bus type '%s' registered\n", bus->name); return 0; +bus_attrs_fail: + kset_unregister(&bus->drivers); bus_drivers_fail: kset_unregister(&bus->devices); bus_devices_fail: -- cgit v1.2.3 From 513e7337adc32cdfbffecb99953e45a44e812c2d Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 22 Sep 2006 11:37:08 +0200 Subject: driver core fixes: bus_add_device() cleanup on error Correct cleanup in the error path of bus_add_device(). Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index b90f6e6f644..d516f7d5f16 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -372,19 +372,30 @@ int bus_add_device(struct device * dev) pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); error = device_add_attrs(bus, dev); if (error) - goto out; + goto out_put; error = sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); if (error) - goto out; + goto out_id; error = sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem"); if (error) - goto out; + goto out_subsys; error = sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); + if (error) + goto out_deprecated; } -out: + return 0; + +out_deprecated: + sysfs_remove_link(&dev->kobj, "subsystem"); +out_subsys: + sysfs_remove_link(&bus->devices.kobj, dev->bus_id); +out_id: + device_remove_attrs(bus, dev); +out_put: + put_bus(dev->bus); return error; } -- cgit v1.2.3 From a306eea40952e6365301e8a2f7d5ffa9c6a1921b Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 22 Sep 2006 11:37:13 +0200 Subject: driver core fixes: device_add() cleanup on error Check for return code of device_create_file() and correct cleanup in the error case in device_add(). Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/base/core.c b/drivers/base/core.c index aee3743bd4a..365f709715e 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -433,14 +433,16 @@ int device_add(struct device *dev) if (dev->driver) dev->uevent_attr.attr.owner = dev->driver->owner; dev->uevent_attr.store = store_uevent; - device_create_file(dev, &dev->uevent_attr); + error = device_create_file(dev, &dev->uevent_attr); + if (error) + goto attrError; if (MAJOR(dev->devt)) { struct device_attribute *attr; attr = kzalloc(sizeof(*attr), GFP_KERNEL); if (!attr) { error = -ENOMEM; - goto PMError; + goto ueventattrError; } attr->attr.name = "dev"; attr->attr.mode = S_IRUGO; @@ -450,7 +452,7 @@ int device_add(struct device *dev) error = device_create_file(dev, attr); if (error) { kfree(attr); - goto attrError; + goto ueventattrError; } dev->devt_attr = attr; @@ -507,6 +509,8 @@ int device_add(struct device *dev) device_remove_file(dev, dev->devt_attr); kfree(dev->devt_attr); } + ueventattrError: + device_remove_file(dev, &dev->uevent_attr); attrError: kobject_uevent(&dev->kobj, KOBJ_REMOVE); kobject_del(&dev->kobj); -- cgit v1.2.3 From 141ecc5320147d363d060cfc8042d197a3cdd496 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 22 Sep 2006 11:37:27 +0200 Subject: driver core fixes: device_create_file() retval check in dmapool.c Check for device_create_file() return value in dma_pool_create(). Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/base/dmapool.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c index 33c5cce1560..b2efbd4cf71 100644 --- a/drivers/base/dmapool.c +++ b/drivers/base/dmapool.c @@ -141,11 +141,20 @@ dma_pool_create (const char *name, struct device *dev, init_waitqueue_head (&retval->waitq); if (dev) { + int ret; + down (&pools_lock); if (list_empty (&dev->dma_pools)) - device_create_file (dev, &dev_attr_pools); + ret = device_create_file (dev, &dev_attr_pools); + else + ret = 0; /* note: not currently insisting "name" be unique */ - list_add (&retval->pools, &dev->dma_pools); + if (!ret) + list_add (&retval->pools, &dev->dma_pools); + else { + kfree(retval); + retval = NULL; + } up (&pools_lock); } else INIT_LIST_HEAD (&retval->pools); -- cgit v1.2.3 From 221c324a336770a911b16bda02b9f4adad506a35 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 22 Sep 2006 11:37:32 +0200 Subject: driver core fixes: sysfs_create_group() retval in topology.c Return the return value of sysfs_create_group() in topology_add_dev(). Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/base/topology.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 3ef9d514b91..28dccb730af 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -97,8 +97,7 @@ static struct attribute_group topology_attr_group = { /* Add/Remove cpu_topology interface for CPU device */ static int __cpuinit topology_add_dev(struct sys_device * sys_dev) { - sysfs_create_group(&sys_dev->kobj, &topology_attr_group); - return 0; + return sysfs_create_group(&sys_dev->kobj, &topology_attr_group); } static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) -- cgit v1.2.3 From 952ab431cd36c7ab573f685af8679c3677cbdc29 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 28 Sep 2006 23:56:01 +0200 Subject: Driver core: Don't leak 'old_class_name' in drivers/base/core.c::device_rename() If kmalloc() fails to allocate space for 'old_symlink_name' in drivers/base/core.c::device_rename(), then we'll leak 'old_class_name'. Spotted by the Coverity checker. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/base/core.c b/drivers/base/core.c index 365f709715e..41f3dca55cd 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -809,8 +809,10 @@ int device_rename(struct device *dev, char *new_name) if (dev->class) { old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); - if (!old_symlink_name) - return -ENOMEM; + if (!old_symlink_name) { + error = -ENOMEM; + goto out_free_old_class; + } strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE); } @@ -834,9 +836,10 @@ int device_rename(struct device *dev, char *new_name) } put_device(dev); - kfree(old_class_name); kfree(new_class_name); kfree(old_symlink_name); + out_free_old_class: + kfree(old_class_name); return error; } -- cgit v1.2.3 From f70fa6296c2ec8f541f0a9b406ccc2d9d127d639 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 5 Oct 2006 17:03:24 -0400 Subject: Driver core: Don't ignore error returns from probing This patch (as797) fixes device_add() in the driver core. It needs to pay attention when the driver for a new device reports an error. At the same time, since bus_remove_device() undoes the effects of both bus_add_device() and bus_attach_device(), it needs to check whether the bus_attach_device step failed. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 6 ++++-- drivers/base/core.c | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index d516f7d5f16..d7c5ea246a0 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -439,8 +439,10 @@ void bus_remove_device(struct device * dev) sysfs_remove_link(&dev->kobj, "bus"); sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); device_remove_attrs(dev->bus, dev); - dev->is_registered = 0; - klist_del(&dev->knode_bus); + if (dev->is_registered) { + dev->is_registered = 0; + klist_del(&dev->knode_bus); + } pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); device_release_driver(dev); put_bus(dev->bus); diff --git a/drivers/base/core.c b/drivers/base/core.c index 41f3dca55cd..68ad11af22b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -479,7 +479,8 @@ int device_add(struct device *dev) if ((error = bus_add_device(dev))) goto BusError; kobject_uevent(&dev->kobj, KOBJ_ADD); - bus_attach_device(dev); + if ((error = bus_attach_device(dev))) + goto AttachError; if (parent) klist_add_tail(&dev->knode_parent, &parent->klist_children); @@ -498,6 +499,8 @@ int device_add(struct device *dev) kfree(class_name); put_device(dev); return error; + AttachError: + bus_remove_device(dev); BusError: device_pm_remove(dev); PMError: -- cgit v1.2.3 From d9fd4d3b317a231e47f31d64d66c8cc7765d458f Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 4 Oct 2006 07:48:03 -0400 Subject: Driver core: bus: remove indentation level Before potentially fixing up these functions, this cosmetic change reduces the indentation level to make the code easier to read and maintain. No functional changes at all. Signed-off-by: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 77 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index d7c5ea246a0..7d8a7ce73fb 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -518,34 +518,36 @@ int bus_add_driver(struct device_driver *drv) struct bus_type * bus = get_bus(drv->bus); int error = 0; - if (bus) { - pr_debug("bus %s: add driver %s\n", bus->name, drv->name); - error = kobject_set_name(&drv->kobj, "%s", drv->name); - if (error) - goto out_put_bus; - drv->kobj.kset = &bus->drivers; - if ((error = kobject_register(&drv->kobj))) - goto out_put_bus; - - error = driver_attach(drv); - if (error) - goto out_unregister; - klist_add_tail(&drv->knode_bus, &bus->klist_drivers); - module_add_driver(drv->owner, drv); - - error = driver_add_attrs(bus, drv); - if (error) { - /* How the hell do we get out of this pickle? Give up */ - printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", - __FUNCTION__, drv->name); - } - error = add_bind_files(drv); - if (error) { - /* Ditto */ - printk(KERN_ERR "%s: add_bind_files(%s) failed\n", - __FUNCTION__, drv->name); - } + if (!bus) + return 0; + + pr_debug("bus %s: add driver %s\n", bus->name, drv->name); + error = kobject_set_name(&drv->kobj, "%s", drv->name); + if (error) + goto out_put_bus; + drv->kobj.kset = &bus->drivers; + if ((error = kobject_register(&drv->kobj))) + goto out_put_bus; + + error = driver_attach(drv); + if (error) + goto out_unregister; + klist_add_tail(&drv->knode_bus, &bus->klist_drivers); + module_add_driver(drv->owner, drv); + + error = driver_add_attrs(bus, drv); + if (error) { + /* How the hell do we get out of this pickle? Give up */ + printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", + __FUNCTION__, drv->name); + } + error = add_bind_files(drv); + if (error) { + /* Ditto */ + printk(KERN_ERR "%s: add_bind_files(%s) failed\n", + __FUNCTION__, drv->name); } + return error; out_unregister: kobject_unregister(&drv->kobj); @@ -565,16 +567,17 @@ out_put_bus: void bus_remove_driver(struct device_driver * drv) { - if (drv->bus) { - remove_bind_files(drv); - driver_remove_attrs(drv->bus, drv); - klist_remove(&drv->knode_bus); - pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); - driver_detach(drv); - module_remove_driver(drv); - kobject_unregister(&drv->kobj); - put_bus(drv->bus); - } + if (!drv->bus) + return; + + remove_bind_files(drv); + driver_remove_attrs(drv->bus, drv); + klist_remove(&drv->knode_bus); + pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); + driver_detach(drv); + module_remove_driver(drv); + kobject_unregister(&drv->kobj); + put_bus(drv->bus); } -- cgit v1.2.3 From 4d664238207a82c4018757e2d87cf2a780462dcd Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 9 Oct 2006 18:04:30 +0900 Subject: driver core: kmalloc() failure check in driver_probe_device driver_probe_device() is missing kmalloc() failure check. Signed-off-by: Akinobu Mita Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/base/dd.c b/drivers/base/dd.c index ef7db6939cb..db01b95a47a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -171,6 +171,8 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) drv->bus->name, dev->bus_id, drv->name); data = kmalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; data->drv = drv; data->dev = dev; -- cgit v1.2.3