Hi Vladimir, > ic_close_dev contains a generalization of the logic to not close a > network interface if it's the host port for a DSA switch. This logic is > disguised behind an iteration through the lowers of ic_dev in > ic_close_dev. > > When no interface for ipconfig can be found, ic_dev is NULL, and > ic_close_dev: > - dereferences a NULL pointer when assigning selected_dev > - would attempt to search through the lower interfaces of a NULL > net_device pointer > > So we should protect against that case. > > The "lower_dev" iterator variable was shortened to "lower" in order to > keep the 80 character limit. > > Fixes: f68cbaed67cb ("net: ipconfig: avoid use-after-free in ic_close_devs") > Fixes: 46acf7bdbc72 ("Revert "net: ipv4: handle DSA enabled master network > devices"") > Signed-off-by: Vladimir Oltean <vladimir.olt...@nxp.com>
Tested-by: Heiko Thiery <heiko.thi...@gmail.com> > --- > net/ipv4/ipconfig.c | 14 ++++++++------ > 1 file changed, 8 insertions(+), 6 deletions(-) > > diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c > index 47db1bfdaaa0..bc2f6ca97152 100644 > --- a/net/ipv4/ipconfig.c > +++ b/net/ipv4/ipconfig.c > @@ -309,7 +309,7 @@ static int __init ic_open_devs(void) > */ > static void __init ic_close_devs(void) > { > - struct net_device *selected_dev = ic_dev->dev; > + struct net_device *selected_dev = ic_dev ? ic_dev->dev : NULL; > struct ic_device *d, *next; > struct net_device *dev; > > @@ -317,16 +317,18 @@ static void __init ic_close_devs(void) > next = ic_first_dev; > while ((d = next)) { > bool bring_down = (d != ic_dev); > - struct net_device *lower_dev; > + struct net_device *lower; > struct list_head *iter; > > next = d->next; > dev = d->dev; > > - netdev_for_each_lower_dev(selected_dev, lower_dev, iter) { > - if (dev == lower_dev) { > - bring_down = false; > - break; > + if (selected_dev) { > + netdev_for_each_lower_dev(selected_dev, lower, iter) { > + if (dev == lower) { > + bring_down = false; > + break; > + } > } > } > if (bring_down) { > -- > 2.25.1 Thank you. -- Heiko