lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri,  1 Dec 2006 15:21:32 -0800
From:	Greg KH <greg@...ah.com>
To:	linux-kernel@...r.kernel.org
Cc:	Kay Sievers <kay.sievers@...ell.com>,
	Greg Kroah-Hartman <gregkh@...e.de>
Subject: [PATCH 2/36] Driver core: fix "driver" symlink timing

From: Kay Sievers <kay.sievers@...ell.com>

Create the "driver" link before the child device may be created by
the probing logic. This makes it possible for userspace (udev), to
determine the driver property of the parent device, at the time the
child device is created.

Signed-off-by: Kay Sievers <kay.sievers@...ell.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...e.de>
---
 drivers/base/dd.c |   82 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 52 insertions(+), 30 deletions(-)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 9c88b1e..510e788 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -26,28 +26,12 @@
 #define to_drv(node) container_of(node, struct device_driver, kobj.entry)
 
 
-/**
- *	device_bind_driver - bind a driver to one device.
- *	@dev:	device.
- *
- *	Allow manual attachment of a driver to a device.
- *	Caller must have already set @dev->driver.
- *
- *	Note that this does not modify the bus reference count
- *	nor take the bus's rwsem. Please verify those are accounted
- *	for before calling this. (It is ok to call with no other effort
- *	from a driver's probe() method.)
- *
- *	This function must be called with @dev->sem held.
- */
-int device_bind_driver(struct device *dev)
+static void driver_bound(struct device *dev)
 {
-	int ret;
-
 	if (klist_node_attached(&dev->knode_driver)) {
 		printk(KERN_WARNING "%s: device %s already bound\n",
 			__FUNCTION__, kobject_name(&dev->kobj));
-		return 0;
+		return;
 	}
 
 	pr_debug("bound device '%s' to driver '%s'\n",
@@ -58,6 +42,12 @@ int device_bind_driver(struct device *de
 					     BUS_NOTIFY_BOUND_DRIVER, dev);
 
 	klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
+}
+
+static int driver_sysfs_add(struct device *dev)
+{
+	int ret;
+
 	ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj,
 			  kobject_name(&dev->kobj));
 	if (ret == 0) {
@@ -70,6 +60,36 @@ int device_bind_driver(struct device *de
 	return ret;
 }
 
+static void driver_sysfs_remove(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+
+	if (drv) {
+		sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
+		sysfs_remove_link(&dev->kobj, "driver");
+	}
+}
+
+/**
+ *	device_bind_driver - bind a driver to one device.
+ *	@dev:	device.
+ *
+ *	Allow manual attachment of a driver to a device.
+ *	Caller must have already set @dev->driver.
+ *
+ *	Note that this does not modify the bus reference count
+ *	nor take the bus's rwsem. Please verify those are accounted
+ *	for before calling this. (It is ok to call with no other effort
+ *	from a driver's probe() method.)
+ *
+ *	This function must be called with @dev->sem held.
+ */
+int device_bind_driver(struct device *dev)
+{
+	driver_bound(dev);
+	return driver_sysfs_add(dev);
+}
+
 struct stupid_thread_structure {
 	struct device_driver *drv;
 	struct device *dev;
@@ -90,30 +110,32 @@ static int really_probe(void *void_data)
 		 drv->bus->name, drv->name, dev->bus_id);
 
 	dev->driver = drv;
+	if (driver_sysfs_add(dev)) {
+		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
+			__FUNCTION__, dev->bus_id);
+		goto probe_failed;
+	}
+
 	if (dev->bus->probe) {
 		ret = dev->bus->probe(dev);
-		if (ret) {
-			dev->driver = NULL;
+		if (ret)
 			goto probe_failed;
-		}
 	} else if (drv->probe) {
 		ret = drv->probe(dev);
-		if (ret) {
-			dev->driver = NULL;
+		if (ret)
 			goto probe_failed;
-		}
-	}
-	if (device_bind_driver(dev)) {
-		printk(KERN_ERR "%s: device_bind_driver(%s) failed\n",
-			__FUNCTION__, dev->bus_id);
-		/* How does undo a ->probe?  We're screwed. */
 	}
+
+	driver_bound(dev);
 	ret = 1;
 	pr_debug("%s: Bound Device %s to Driver %s\n",
 		 drv->bus->name, dev->bus_id, drv->name);
 	goto done;
 
 probe_failed:
+	driver_sysfs_remove(dev);
+	dev->driver = NULL;
+
 	if (ret == -ENODEV || ret == -ENXIO) {
 		/* Driver matched, but didn't support device
 		 * or device not found.
@@ -289,7 +311,7 @@ static void __device_release_driver(stru
 	drv = dev->driver;
 	if (drv) {
 		get_driver(drv);
-		sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
+		driver_sysfs_remove(dev);
 		sysfs_remove_link(&dev->kobj, "driver");
 		klist_remove(&dev->knode_driver);
 
-- 
1.4.4.1

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ