Message ID | 20200618034245.29928-1-f.fainelli@gmail.com |
---|---|
State | Accepted |
Delegated to: | David Miller |
Headers | show |
Series | [net] net: dsa: bcm_sf2: Fix node reference count | expand |
On Wed, Jun 17, 2020 at 08:42:44PM -0700, Florian Fainelli wrote: > of_find_node_by_name() will do an of_node_put() on the "from" argument. > Fixes: afa3b592953b ("net: dsa: bcm_sf2: Ensure correct sub-node is parsed") > Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> > --- > drivers/net/dsa/bcm_sf2.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c > index c1bd21e4b15c..9f62ba3e4345 100644 > --- a/drivers/net/dsa/bcm_sf2.c > +++ b/drivers/net/dsa/bcm_sf2.c > @@ -1154,6 +1154,8 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) > set_bit(0, priv->cfp.used); > set_bit(0, priv->cfp.unique); > > + /* Balance of_node_put() done by of_find_node_by_name() */ > + of_node_get(dn); > ports = of_find_node_by_name(dn, "ports"); That if_find_node_by_name() does a put is not very intuitive. Maybe document that as well in the kerneldocs? Reviewed-by: Andrew Lunn <andrew@lunn.ch> Andrew
On 6/18/2020 5:56 AM, Andrew Lunn wrote: > On Wed, Jun 17, 2020 at 08:42:44PM -0700, Florian Fainelli wrote: >> of_find_node_by_name() will do an of_node_put() on the "from" argument. > >> Fixes: afa3b592953b ("net: dsa: bcm_sf2: Ensure correct sub-node is parsed") >> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> >> --- >> drivers/net/dsa/bcm_sf2.c | 2 ++ >> 1 file changed, 2 insertions(+) >> >> diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c >> index c1bd21e4b15c..9f62ba3e4345 100644 >> --- a/drivers/net/dsa/bcm_sf2.c >> +++ b/drivers/net/dsa/bcm_sf2.c >> @@ -1154,6 +1154,8 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) >> set_bit(0, priv->cfp.used); >> set_bit(0, priv->cfp.unique); >> >> + /* Balance of_node_put() done by of_find_node_by_name() */ >> + of_node_get(dn); >> ports = of_find_node_by_name(dn, "ports"); > > That if_find_node_by_name() does a put is not very intuitive. > Maybe document that as well in the kerneldocs? Yes that is the plan, most callers call it with a NULL from argument but that is a bit silly if you know what the Device Tree looks like, you can search quicker to the target node. Thanks. > > Reviewed-by: Andrew Lunn <andrew@lunn.ch> > > Andrew >
From: Andrew Lunn <andrew@lunn.ch> Date: Thu, 18 Jun 2020 14:56:40 +0200 > That if_find_node_by_name() does a put is not very intuitive. > Maybe document that as well in the kerneldocs? > > Reviewed-by: Andrew Lunn <andrew@lunn.ch> I've been complaining about the non-intuitiveness of the various OF interfaces for a long time. They transfer reference counts across objects, and that makes the logic hard to audit. The iterators are the worst.
From: Florian Fainelli <f.fainelli@gmail.com> Date: Wed, 17 Jun 2020 20:42:44 -0700 > of_find_node_by_name() will do an of_node_put() on the "from" argument. > With CONFIG_OF_DYNAMIC enabled which checks for device_node reference > counts, we would be getting a warning like this: ... > Fix this by adding a of_node_get() to increment the reference count > prior to the call. > > Fixes: afa3b592953b ("net: dsa: bcm_sf2: Ensure correct sub-node is parsed") > Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Applied and queued up for v5.7 -stable, thanks.
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index c1bd21e4b15c..9f62ba3e4345 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -1154,6 +1154,8 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) set_bit(0, priv->cfp.used); set_bit(0, priv->cfp.unique); + /* Balance of_node_put() done by of_find_node_by_name() */ + of_node_get(dn); ports = of_find_node_by_name(dn, "ports"); if (ports) { bcm_sf2_identify_ports(priv, ports);
of_find_node_by_name() will do an of_node_put() on the "from" argument. With CONFIG_OF_DYNAMIC enabled which checks for device_node reference counts, we would be getting a warning like this: [ 6.347230] refcount_t: increment on 0; use-after-free. [ 6.352498] WARNING: CPU: 3 PID: 77 at lib/refcount.c:156 refcount_inc_checked+0x38/0x44 [ 6.360601] Modules linked in: [ 6.363661] CPU: 3 PID: 77 Comm: kworker/3:1 Tainted: G W 5.4.46-gb78b3e9956e6 #13 [ 6.372546] Hardware name: BCM97278SV (DT) [ 6.376649] Workqueue: events deferred_probe_work_func [ 6.381796] pstate: 60000005 (nZCv daif -PAN -UAO) [ 6.386595] pc : refcount_inc_checked+0x38/0x44 [ 6.391133] lr : refcount_inc_checked+0x38/0x44 ... [ 6.478791] Call trace: [ 6.481243] refcount_inc_checked+0x38/0x44 [ 6.485433] kobject_get+0x3c/0x4c [ 6.488840] of_node_get+0x24/0x34 [ 6.492247] of_irq_find_parent+0x3c/0xe0 [ 6.496263] of_irq_parse_one+0xe4/0x1d0 [ 6.500191] irq_of_parse_and_map+0x44/0x84 [ 6.504381] bcm_sf2_sw_probe+0x22c/0x844 [ 6.508397] platform_drv_probe+0x58/0xa8 [ 6.512413] really_probe+0x238/0x3fc [ 6.516081] driver_probe_device+0x11c/0x12c [ 6.520358] __device_attach_driver+0xa8/0x100 [ 6.524808] bus_for_each_drv+0xb4/0xd0 [ 6.528650] __device_attach+0xd0/0x164 [ 6.532493] device_initial_probe+0x24/0x30 [ 6.536682] bus_probe_device+0x38/0x98 [ 6.540524] deferred_probe_work_func+0xa8/0xd4 [ 6.545061] process_one_work+0x178/0x288 [ 6.549078] process_scheduled_works+0x44/0x48 [ 6.553529] worker_thread+0x218/0x270 [ 6.557285] kthread+0xdc/0xe4 [ 6.560344] ret_from_fork+0x10/0x18 [ 6.563925] ---[ end trace 68f65caf69bb152a ]--- Fix this by adding a of_node_get() to increment the reference count prior to the call. Fixes: afa3b592953b ("net: dsa: bcm_sf2: Ensure correct sub-node is parsed") Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> --- drivers/net/dsa/bcm_sf2.c | 2 ++ 1 file changed, 2 insertions(+)