diff options
author | Wang Chen <wangchen@cn.fujitsu.com> | 2008-07-14 23:59:03 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-14 23:59:03 -0400 |
commit | 89146504cbfeb120dd08ec7f9f8314c4986189b8 (patch) | |
tree | 7a271a017d3e622aa3a3459b3d1b0bbecd4bd9e6 /net/8021q | |
parent | b89fb7da2f9a69dd34ff10d45f66baa40ff8c0e5 (diff) |
8021q: Check return of dev_set_promiscuity/allmulti
dev_set_promiscuity/allmulti might overflow.
Commit: "netdevice: Fix promiscuity and allmulti overflow" in net-next makes
dev_set_promiscuity/allmulti return error number if overflow happened.
Here, we check all positive increment for promiscuity and allmulti
to get error return.
Signed-off-by: Wang Chen <wangchen@cn.fujitsu.com>
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q')
-rw-r--r-- | net/8021q/vlan_dev.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 8efa399823e3..9efd3c67c1db 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -518,19 +518,35 @@ static int vlan_dev_open(struct net_device *dev) | |||
518 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { | 518 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { |
519 | err = dev_unicast_add(real_dev, dev->dev_addr, ETH_ALEN); | 519 | err = dev_unicast_add(real_dev, dev->dev_addr, ETH_ALEN); |
520 | if (err < 0) | 520 | if (err < 0) |
521 | return err; | 521 | goto out; |
522 | } | 522 | } |
523 | memcpy(vlan->real_dev_addr, real_dev->dev_addr, ETH_ALEN); | ||
524 | 523 | ||
525 | if (dev->flags & IFF_ALLMULTI) | 524 | if (dev->flags & IFF_ALLMULTI) { |
526 | dev_set_allmulti(real_dev, 1); | 525 | err = dev_set_allmulti(real_dev, 1); |
527 | if (dev->flags & IFF_PROMISC) | 526 | if (err < 0) |
528 | dev_set_promiscuity(real_dev, 1); | 527 | goto del_unicast; |
528 | } | ||
529 | if (dev->flags & IFF_PROMISC) { | ||
530 | err = dev_set_promiscuity(real_dev, 1); | ||
531 | if (err < 0) | ||
532 | goto clear_allmulti; | ||
533 | } | ||
534 | |||
535 | memcpy(vlan->real_dev_addr, real_dev->dev_addr, ETH_ALEN); | ||
529 | 536 | ||
530 | if (vlan->flags & VLAN_FLAG_GVRP) | 537 | if (vlan->flags & VLAN_FLAG_GVRP) |
531 | vlan_gvrp_request_join(dev); | 538 | vlan_gvrp_request_join(dev); |
532 | 539 | ||
533 | return 0; | 540 | return 0; |
541 | |||
542 | clear_allmulti: | ||
543 | if (dev->flags & IFF_ALLMULTI) | ||
544 | dev_set_allmulti(real_dev, -1); | ||
545 | del_unicast: | ||
546 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | ||
547 | dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN); | ||
548 | out: | ||
549 | return err; | ||
534 | } | 550 | } |
535 | 551 | ||
536 | static int vlan_dev_stop(struct net_device *dev) | 552 | static int vlan_dev_stop(struct net_device *dev) |