From 51106cb1fd14dfbf62c2760921463376f56ac732 Mon Sep 17 00:00:00 2001 From: Bogdan Purcareata Date: Tue, 21 Jun 2016 18:40:47 +0000 Subject: [PATCH 205/226] fsl-dpaa2: eth: sanitize supported private flags On linux-v4.6 with CONFIG_MACVLAN=y, when bringing up a ni interface, the network stack crashes due to a segfault. This is related to the macvlan_device_event notifier, which registers itself to all the network interface in the system. The notifier reads the netdev private flags and incorrectly qualifies the interface as a macvlan port, since both the IFF_MACVLAN_PORT and IFF_PROMISC flags have the same offset. Code spelunking reveals that IFF_PROMISC is only used as an interface flag, not a private interface flag. A similar situation happens with IFF_ALLMULTI, which overlaps with IFF_BRIDGE_PORT. No info on the consequences of this, since I haven't tested bridge scenarios. The interface can still be set in allmulti mode using userspace tools (e.g. ifconfig). IFF_MULTICAST overlaps with IFF_UNICAST_FLT, therefore the current code has no effect as it is. The closest multicast activation based on device capabilities has been seen in the case of the Aeroflex Gaisler Ethernet MAC (aeroflex/greth.c) - here, the runtime (not private) flag is set on device probe. On a side node, ether_setup enables IFF_MULTICAST by default. Remove IFF_PROMISC, IFF_ALLMULTI and IFF_MULTICAST from device capabilities init. Signed-off-by: Bogdan Purcareata --- drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) --- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c +++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c @@ -1176,18 +1176,13 @@ static int dpaa2_eth_init(struct net_dev u32 options = priv->dpni_attrs.options; /* Capabilities listing */ - supported |= IFF_LIVE_ADDR_CHANGE | IFF_PROMISC | IFF_ALLMULTI; + supported |= IFF_LIVE_ADDR_CHANGE; if (options & DPNI_OPT_UNICAST_FILTER) supported |= IFF_UNICAST_FLT; else not_supported |= IFF_UNICAST_FLT; - if (options & DPNI_OPT_MULTICAST_FILTER) - supported |= IFF_MULTICAST; - else - not_supported |= IFF_MULTICAST; - net_dev->priv_flags |= supported; net_dev->priv_flags &= ~not_supported;