diff options
author | Ben Greear <greearb@candelatech.com> | 2011-06-01 03:18:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-05 17:16:28 -0400 |
commit | 160ff18a07f3a505d452dcced8e45ecdd0a85506 (patch) | |
tree | 68faa9997e62de66cfc0f06ed744737443345c7f /net/packet | |
parent | e990b37b906b6137d353ef2a918e15e5763d70ec (diff) |
af-packet: Hold reference to bound network devices.
Old code was probably safe, but with this change we
can actually use the netdev object, not just compare
the pointer values.
Signed-off-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/packet')
-rw-r--r-- | net/packet/af_packet.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ba248d93399a..636b75c15a63 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1342,6 +1342,10 @@ static int packet_release(struct socket *sock) | |||
1342 | __dev_remove_pack(&po->prot_hook); | 1342 | __dev_remove_pack(&po->prot_hook); |
1343 | __sock_put(sk); | 1343 | __sock_put(sk); |
1344 | } | 1344 | } |
1345 | if (po->prot_hook.dev) { | ||
1346 | dev_put(po->prot_hook.dev); | ||
1347 | po->prot_hook.dev = NULL; | ||
1348 | } | ||
1345 | spin_unlock(&po->bind_lock); | 1349 | spin_unlock(&po->bind_lock); |
1346 | 1350 | ||
1347 | packet_flush_mclist(sk); | 1351 | packet_flush_mclist(sk); |
@@ -1395,6 +1399,8 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc | |||
1395 | 1399 | ||
1396 | po->num = protocol; | 1400 | po->num = protocol; |
1397 | po->prot_hook.type = protocol; | 1401 | po->prot_hook.type = protocol; |
1402 | if (po->prot_hook.dev) | ||
1403 | dev_put(po->prot_hook.dev); | ||
1398 | po->prot_hook.dev = dev; | 1404 | po->prot_hook.dev = dev; |
1399 | 1405 | ||
1400 | po->ifindex = dev ? dev->ifindex : 0; | 1406 | po->ifindex = dev ? dev->ifindex : 0; |
@@ -1439,10 +1445,8 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, | |||
1439 | strlcpy(name, uaddr->sa_data, sizeof(name)); | 1445 | strlcpy(name, uaddr->sa_data, sizeof(name)); |
1440 | 1446 | ||
1441 | dev = dev_get_by_name(sock_net(sk), name); | 1447 | dev = dev_get_by_name(sock_net(sk), name); |
1442 | if (dev) { | 1448 | if (dev) |
1443 | err = packet_do_bind(sk, dev, pkt_sk(sk)->num); | 1449 | err = packet_do_bind(sk, dev, pkt_sk(sk)->num); |
1444 | dev_put(dev); | ||
1445 | } | ||
1446 | return err; | 1450 | return err; |
1447 | } | 1451 | } |
1448 | 1452 | ||
@@ -1470,8 +1474,6 @@ static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len | |||
1470 | goto out; | 1474 | goto out; |
1471 | } | 1475 | } |
1472 | err = packet_do_bind(sk, dev, sll->sll_protocol ? : pkt_sk(sk)->num); | 1476 | err = packet_do_bind(sk, dev, sll->sll_protocol ? : pkt_sk(sk)->num); |
1473 | if (dev) | ||
1474 | dev_put(dev); | ||
1475 | 1477 | ||
1476 | out: | 1478 | out: |
1477 | return err; | 1479 | return err; |
@@ -2240,6 +2242,8 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void | |||
2240 | } | 2242 | } |
2241 | if (msg == NETDEV_UNREGISTER) { | 2243 | if (msg == NETDEV_UNREGISTER) { |
2242 | po->ifindex = -1; | 2244 | po->ifindex = -1; |
2245 | if (po->prot_hook.dev) | ||
2246 | dev_put(po->prot_hook.dev); | ||
2243 | po->prot_hook.dev = NULL; | 2247 | po->prot_hook.dev = NULL; |
2244 | } | 2248 | } |
2245 | spin_unlock(&po->bind_lock); | 2249 | spin_unlock(&po->bind_lock); |