af_packet: 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.

In af_packet, 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>
This commit is contained in:
Wang Chen 2008-07-14 20:49:46 -07:00 committed by David S. Miller
parent fc943b12e4
commit 2aeb0b88b3
1 changed files with 10 additions and 4 deletions

View File

@ -1173,7 +1173,8 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
return 0; return 0;
} }
static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int what) static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
int what)
{ {
switch (i->type) { switch (i->type) {
case PACKET_MR_MULTICAST: case PACKET_MR_MULTICAST:
@ -1183,13 +1184,14 @@ static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int w
dev_mc_delete(dev, i->addr, i->alen, 0); dev_mc_delete(dev, i->addr, i->alen, 0);
break; break;
case PACKET_MR_PROMISC: case PACKET_MR_PROMISC:
dev_set_promiscuity(dev, what); return dev_set_promiscuity(dev, what);
break; break;
case PACKET_MR_ALLMULTI: case PACKET_MR_ALLMULTI:
dev_set_allmulti(dev, what); return dev_set_allmulti(dev, what);
break; break;
default:; default:;
} }
return 0;
} }
static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what) static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what)
@ -1243,7 +1245,11 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
i->count = 1; i->count = 1;
i->next = po->mclist; i->next = po->mclist;
po->mclist = i; po->mclist = i;
packet_dev_mc(dev, i, +1); err = packet_dev_mc(dev, i, 1);
if (err) {
po->mclist = i->next;
kfree(i);
}
done: done:
rtnl_unlock(); rtnl_unlock();