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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 10 Dec 2013 16:13:53 +0200
From:	Pantelis Antoniou <panto@...oniou-consulting.com>
To:	Grant Likely <grant.likely@...retlab.ca>
Cc:	Rob Herring <robherring2@...il.com>,
	Stephen Warren <swarren@...dotorg.org>,
	Matt Porter <matt.porter@...aro.org>,
	Koen Kooi <koen@...inion.thruhere.net>,
	Alison Chaiken <Alison_Chaiken@...tor.com>,
	Dinh Nguyen <dinh.linux@...il.com>,
	Jan Lubbe <jluebbe@...net.de>,
	Alexander Sverdlin <alexander.sverdlin@....com>,
	Michael Stickel <ms@...able.de>,
	Guenter Roeck <linux@...ck-us.net>,
	Dirk Behme <dirk.behme@...il.com>,
	Alan Tull <delicious.quinoa@...il.com>,
	Sascha Hauer <s.hauer@...gutronix.de>,
	Michael Bohan <mbohan@...eaurora.org>,
	Ionut Nicu <ioan.nicu.ext@....com>,
	Michal Simek <monstr@...str.eu>,
	Matt Ranostay <mranostay@...il.com>,
	devicetree@...r.kernel.org, linux-kernel@...r.kernel.org,
	Pantelis Antoniou <panto@...oniou-consulting.com>
Subject: [PATCH 3/3] OF: kobj ops should only happen on attached nodes

kobject operation should only take place on already attached (live)
device nodes. The same restriction applies to the invocation of
device tree notifiers.

Introduce a simple of_node_is_attached() test which tests whether
the given node is attached via means of the allnodes member.

Signed-off-by: Pantelis Antoniou <panto@...oniou-consulting.com>
---
 drivers/of/base.c | 87 ++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 64 insertions(+), 23 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index db0de86..c6299bd 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -89,6 +89,13 @@ int __weak of_node_to_nid(struct device_node *np)
 #endif
 
 #if defined(CONFIG_OF_DYNAMIC)
+
+/* simple test for figuring out if node is attached */
+static inline int of_node_is_attached(struct device_node *np)
+{
+	return np && np->allnodes == &of_allnodes;
+}
+
 /**
  *	of_node_get - Increment refcount of a node
  *	@node:	Node to inc refcount, NULL is supported to
@@ -98,7 +105,7 @@ int __weak of_node_to_nid(struct device_node *np)
  */
 struct device_node *of_node_get(struct device_node *node)
 {
-	if (node && of_kset)
+	if (node && of_kset && of_node_is_attached(node))
 		kobject_get(&node->kobj);
 	return node;
 }
@@ -156,7 +163,7 @@ static void of_node_release(struct kobject *kobj)
  */
 void of_node_put(struct device_node *node)
 {
-	if (node && of_kset)
+	if (node && of_kset && of_node_is_attached(node))
 		kobject_put(&node->kobj);
 }
 EXPORT_SYMBOL(of_node_put);
@@ -210,6 +217,10 @@ static int __of_add_property(struct device_node *np, struct property *pp)
 	if (!of_kset)
 		return 0;
 
+	/* don't do anything with a detached node */
+	if (!of_node_is_attached(np))
+		return 0;
+
 	/* Important: Don't leak passwords */
 	secure = strncmp(pp->name, "security-", 9) == 0;
 
@@ -235,6 +246,9 @@ static int __of_node_add(struct device_node *np)
 	if (!of_kset)
 		return 0;
 
+	if (!of_node_is_attached(np))
+		return 0;
+
 	np->kobj.kset = of_kset;
 	if (!np->parent) {
 		/* Nodes without parents are new top level trees */
@@ -259,6 +273,9 @@ int of_node_add(struct device_node *np)
 {
 	int rc = 0;
 
+	if (!of_node_is_attached(np))
+		return 0;
+
 	/* fake the return while of_init is not yet called */
 	mutex_lock(&of_aliases_mutex);
 	kobject_init(&np->kobj, &of_node_ktype);
@@ -274,10 +291,16 @@ static void of_node_remove(struct device_node *np)
 {
 	struct property *pp;
 
+	/* don't do anything with a detached node */
+	if (!of_node_is_attached(np))
+		return;
+
 	for_each_property_of_node(np, pp)
 		sysfs_remove_bin_file(&np->kobj, &pp->attr);
 
 	kobject_del(&np->kobj);
+
+	of_node_put(np);
 }
 #endif
 
@@ -1626,9 +1649,11 @@ int of_add_property(struct device_node *np, struct property *prop)
 	unsigned long flags;
 	int rc;
 
-	rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop);
-	if (rc)
-		return rc;
+	if (of_node_is_attached(np)) {
+		rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop);
+		if (rc)
+			return rc;
+	}
 
 	prop->next = NULL;
 	raw_spin_lock_irqsave(&devtree_lock, flags);
@@ -1664,9 +1689,11 @@ int of_remove_property(struct device_node *np, struct property *prop)
 	int found = 0;
 	int rc;
 
-	rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop);
-	if (rc)
-		return rc;
+	if (of_node_is_attached(np)) {
+		rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop);
+		if (rc)
+			return rc;
+	}
 
 	raw_spin_lock_irqsave(&devtree_lock, flags);
 	next = &np->properties;
@@ -1686,7 +1713,8 @@ int of_remove_property(struct device_node *np, struct property *prop)
 	if (!found)
 		return -ENODEV;
 
-	sysfs_remove_bin_file(&np->kobj, &prop->attr);
+	if (of_node_is_attached(np))
+		sysfs_remove_bin_file(&np->kobj, &prop->attr);
 
 	return 0;
 }
@@ -1706,9 +1734,11 @@ int of_update_property(struct device_node *np, struct property *newprop)
 	unsigned long flags;
 	int rc, found = 0;
 
-	rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
-	if (rc)
-		return rc;
+	if (of_node_is_attached(np)) {
+		rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
+		if (rc)
+			return rc;
+	}
 
 	if (!newprop->name)
 		return -EINVAL;
@@ -1736,9 +1766,11 @@ int of_update_property(struct device_node *np, struct property *newprop)
 	if (!found)
 		return -ENODEV;
 
-	/* Update the sysfs attribute */
-	sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
-	__of_add_property(np, newprop);
+	if (of_node_is_attached(np)) {
+		/* Update the sysfs attribute */
+		sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
+		__of_add_property(np, newprop);
+	}
 
 	return 0;
 }
@@ -1782,10 +1814,6 @@ int of_attach_node(struct device_node *np)
 	unsigned long flags;
 	int rc;
 
-	rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
-	if (rc)
-		return rc;
-
 	raw_spin_lock_irqsave(&devtree_lock, flags);
 	np->sibling = np->parent->child;
 	np->allnext = of_allnodes;
@@ -1794,7 +1822,18 @@ int of_attach_node(struct device_node *np)
 	np->allnodes = &of_allnodes;
 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
 
-	of_node_add(np);
+	rc = of_node_add(np);
+	if (rc != 0)
+		goto err_detach;
+
+	rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
+	if (rc)
+		goto err_detach;
+
+	return 0;
+
+err_detach:
+	of_node_remove(np);
 	return 0;
 }
 
@@ -1810,9 +1849,11 @@ int of_detach_node(struct device_node *np)
 	unsigned long flags;
 	int rc = 0;
 
-	rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
-	if (rc)
-		return rc;
+	if (of_node_is_attached(np)) {
+		rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
+		if (rc)
+			return rc;
+	}
 
 	raw_spin_lock_irqsave(&devtree_lock, flags);
 
-- 
1.7.12

--
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