diff options
author | Wang Chen <wangchen@cn.fujitsu.com> | 2008-07-14 23:49:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-14 23:49:46 -0400 |
commit | 2aeb0b88b3c7a0e3bef55e7ff0efffd5d971aa57 (patch) | |
tree | 5b944f469ab809b4e88f6b25b99e8488f58983ce /net | |
parent | fc943b12e48f9341bce48c2fadf094cc721aab93 (diff) |
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/packet/af_packet.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index beca6402f1cf..9f2269166687 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1173,7 +1173,8 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1173 | return 0; | 1173 | return 0; |
1174 | } | 1174 | } |
1175 | 1175 | ||
1176 | static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int what) | 1176 | static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, |
1177 | int what) | ||
1177 | { | 1178 | { |
1178 | switch (i->type) { | 1179 | switch (i->type) { |
1179 | case PACKET_MR_MULTICAST: | 1180 | case PACKET_MR_MULTICAST: |
@@ -1183,13 +1184,14 @@ static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int w | |||
1183 | dev_mc_delete(dev, i->addr, i->alen, 0); | 1184 | dev_mc_delete(dev, i->addr, i->alen, 0); |
1184 | break; | 1185 | break; |
1185 | case PACKET_MR_PROMISC: | 1186 | case PACKET_MR_PROMISC: |
1186 | dev_set_promiscuity(dev, what); | 1187 | return dev_set_promiscuity(dev, what); |
1187 | break; | 1188 | break; |
1188 | case PACKET_MR_ALLMULTI: | 1189 | case PACKET_MR_ALLMULTI: |
1189 | dev_set_allmulti(dev, what); | 1190 | return dev_set_allmulti(dev, what); |
1190 | break; | 1191 | break; |
1191 | default:; | 1192 | default:; |
1192 | } | 1193 | } |
1194 | return 0; | ||
1193 | } | 1195 | } |
1194 | 1196 | ||
1195 | static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what) | 1197 | 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) | |||
1243 | i->count = 1; | 1245 | i->count = 1; |
1244 | i->next = po->mclist; | 1246 | i->next = po->mclist; |
1245 | po->mclist = i; | 1247 | po->mclist = i; |
1246 | packet_dev_mc(dev, i, +1); | 1248 | err = packet_dev_mc(dev, i, 1); |
1249 | if (err) { | ||
1250 | po->mclist = i->next; | ||
1251 | kfree(i); | ||
1252 | } | ||
1247 | 1253 | ||
1248 | done: | 1254 | done: |
1249 | rtnl_unlock(); | 1255 | rtnl_unlock(); |