Re: [PATCH 2/2] device property: fix for a case of use-after-free

From: Andy Shevchenko
Date: Mon Feb 22 2016 - 10:40:16 EST


On Mon, 2016-02-22 at 16:50 +0200, Heikki Krogerus wrote:
> In device_remove_property_set(), if the primary fwnode is
> of type "pset", it has to be set pointing to NULL before
> calling set_secondary_fwnode(). Otherwise
> set_secondary_fwnode() will attempt to set the
> fwnode->secondary member after the fwnode has been freed.
>
> Reported-by: John Youn <John.Youn@xxxxxxxxxxxx>
> Signed-off-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx>
> ---
> Âdrivers/base/property.c | 4 +++-
> Â1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/base/property.c b/drivers/base/property.c
> index a163f2c..ddf2987 100644
> --- a/drivers/base/property.c
> +++ b/drivers/base/property.c
> @@ -820,7 +820,9 @@ void device_remove_property_set(struct device
> *dev)
> Â Â* the pset. If there is no real firmware node (ACPI/DT)
> primary
> Â Â* will hold the pset.
> Â Â*/
> - if (!is_pset_node(fwnode))
> + if (is_pset_node(fwnode))
> + dev->fwnode = NULL;
> + else
> Â fwnode = fwnode->secondary;
> Â if (!IS_ERR(fwnode) && is_pset_node(fwnode))
> Â pset_free_set(to_pset_node(fwnode));


What if we do the following

--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -818,9 +818,13 @@ void device_remove_property_set(struct device
*dev)
ÂÂÂÂÂÂÂÂÂ*/
ÂÂÂÂÂÂÂÂif (!is_pset_node(fwnode))
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂfwnode = fwnode->secondary;
+
+ÂÂÂÂÂÂÂ/* Set device fwnode to NULL before we free it */
+ÂÂÂÂÂÂÂset_secondary_fwnode(dev, NULL);
+
+ÂÂÂÂÂÂÂ/* Free property set for the given device */
ÂÂÂÂÂÂÂÂif (!IS_ERR(fwnode) && is_pset_node(fwnode))
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂpset_free_set(to_pset_node(fwnode));
-ÂÂÂÂÂÂÂset_secondary_fwnode(dev, NULL);
Â}
ÂEXPORT_SYMBOL_GPL(device_remove_property_set);
Â
?

--
Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
Intel Finland Oy