Skip to content

Commit

Permalink
net: fix rtnetlink IFF_PROMISC and IFF_ALLMULTI handling
Browse files Browse the repository at this point in the history
When device flags are set using rtnetlink, IFF_PROMISC and IFF_ALLMULTI
flags are handled specially. Function dev_change_flags sets IFF_PROMISC and
IFF_ALLMULTI bits in dev->gflags according to the passed value but
do_setlink passes a result of rtnl_dev_combine_flags which takes those bits
from dev->flags.

This can be easily trigerred by doing:

tcpdump -i eth0 &
ip l s up eth0

ip sets IFF_UP flag in ifi_flags and ifi_change, which is combined with
IFF_PROMISC by rtnl_dev_combine_flags, causing __dev_change_flags to set
IFF_PROMISC in gflags.

Reported-by: Max Matveev <makc@redhat.com>
Signed-off-by: Jiri Benc <jbenc@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jiri Benc authored and David S. Miller committed Jul 27, 2012
1 parent e4c7f25 commit b1beb68
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,12 @@ static void set_operstate(struct net_device *dev, unsigned char transition)
}
}

static unsigned int rtnl_dev_get_flags(const struct net_device *dev)
{
return (dev->flags & ~(IFF_PROMISC | IFF_ALLMULTI)) |
(dev->gflags & (IFF_PROMISC | IFF_ALLMULTI));
}

static unsigned int rtnl_dev_combine_flags(const struct net_device *dev,
const struct ifinfomsg *ifm)
{
Expand All @@ -667,7 +673,7 @@ static unsigned int rtnl_dev_combine_flags(const struct net_device *dev,
/* bugwards compatibility: ifi_change == 0 is treated as ~0 */
if (ifm->ifi_change)
flags = (flags & ifm->ifi_change) |
(dev->flags & ~ifm->ifi_change);
(rtnl_dev_get_flags(dev) & ~ifm->ifi_change);

return flags;
}
Expand Down

0 comments on commit b1beb68

Please sign in to comment.