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]
Message-Id: <20131211131450.EE33BC4061A@trevor.secretlab.ca>
Date:	Wed, 11 Dec 2013 13:14:50 +0000
From:	Grant Likely <grant.likely@...retlab.ca>
To:	Pantelis Antoniou <panto@...oniou-consulting.com>
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: Re: [PATCH 3/3] OF: kobj ops should only happen on attached nodes

On Tue, 10 Dec 2013 16:13:53 +0200, Pantelis Antoniou <panto@...oniou-consulting.com> wrote:
> 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);

Remind me, what is the reason for not wanting to refcount unattached
nodes? I would think that doing a refcount is still desirable, even if
it doesn't show up in sysfs.

I know we talked about this on IRC, but I don't remember the conclusion
we came to.

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

I'm concerned about this whole approach. It "feels" wrong to me.
Perhaps the mistake is to having the unflatten routine be the one also
adding the nodes to the tree. The whole thing could be sidestepped if
unflattening the data structure was a completely separate step from
attaching it to the live tree.

We could rework fdt.c (and pdt.c) to not touch allnodes at all and then
have a separate function that walks the unflattened device tree and
attaches the lot at once. That would make it easier for you to grab an
unflattened tree and work with it before adding nodes to the core tree.

>  	/* 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;
> +

I'm pretty sure the notifier is where it is to allow a notifier callback
to intercepted it before it gets attached to the tree. I suspect this
change will break prom_reconfig_notifier. Notifying after
attachment, or before removal will require a separate set of notifiers.

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