aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2013-12-06 05:36:15 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-15 18:28:46 -0500
commitc3ac8a134305ed1522d8987e62249a85efb09c98 (patch)
tree0ba2f10ff56d4b922f3f062d5272d14edee0c556
parent4ea85d9e4113ba0b2d67d762a29c809df948426a (diff)
packet: fix send path when running with proto == 0
[ Upstream commit 66e56cd46b93ef407c60adcac62cf33b06119d50 ] Commit e40526cb20b5 introduced a cached dev pointer, that gets hooked into register_prot_hook(), __unregister_prot_hook() to update the device used for the send path. We need to fix this up, as otherwise this will not work with sockets created with protocol = 0, plus with sll_protocol = 0 passed via sockaddr_ll when doing the bind. So instead, assign the pointer directly. The compiler can inline these helper functions automagically. While at it, also assume the cached dev fast-path as likely(), and document this variant of socket creation as it seems it is not widely used (seems not even the author of TX_RING was aware of that in his reference example [1]). Tested with reproducer from e40526cb20b5. [1] http://wiki.ipxwarzone.com/index.php5?title=Linux_packet_mmap#Example Fixes: e40526cb20b5 ("packet: fix use after free race in send path when dev is released") Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Tested-by: Salam Noureddine <noureddine@aristanetworks.com> Tested-by: Jesper Dangaard Brouer <brouer@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--Documentation/networking/packet_mmap.txt10
-rw-r--r--net/packet/af_packet.c65
2 files changed, 50 insertions, 25 deletions
diff --git a/Documentation/networking/packet_mmap.txt b/Documentation/networking/packet_mmap.txt
index 23dd80e82b8e..0f4376ec8852 100644
--- a/Documentation/networking/packet_mmap.txt
+++ b/Documentation/networking/packet_mmap.txt
@@ -123,6 +123,16 @@ Transmission process is similar to capture as shown below.
123[shutdown] close() --------> destruction of the transmission socket and 123[shutdown] close() --------> destruction of the transmission socket and
124 deallocation of all associated resources. 124 deallocation of all associated resources.
125 125
126Socket creation and destruction is also straight forward, and is done
127the same way as in capturing described in the previous paragraph:
128
129 int fd = socket(PF_PACKET, mode, 0);
130
131The protocol can optionally be 0 in case we only want to transmit
132via this socket, which avoids an expensive call to packet_rcv().
133In this case, you also need to bind(2) the TX_RING with sll_protocol = 0
134set. Otherwise, htons(ETH_P_ALL) or any other protocol, for example.
135
126Binding the socket to your network interface is mandatory (with zero copy) to 136Binding the socket to your network interface is mandatory (with zero copy) to
127know the header size of frames used in the circular buffer. 137know the header size of frames used in the circular buffer.
128 138
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index c503ad6f610f..e8b5a0dfca21 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -237,6 +237,30 @@ struct packet_skb_cb {
237static void __fanout_unlink(struct sock *sk, struct packet_sock *po); 237static void __fanout_unlink(struct sock *sk, struct packet_sock *po);
238static void __fanout_link(struct sock *sk, struct packet_sock *po); 238static void __fanout_link(struct sock *sk, struct packet_sock *po);
239 239
240static struct net_device *packet_cached_dev_get(struct packet_sock *po)
241{
242 struct net_device *dev;
243
244 rcu_read_lock();
245 dev = rcu_dereference(po->cached_dev);
246 if (likely(dev))
247 dev_hold(dev);
248 rcu_read_unlock();
249
250 return dev;
251}
252
253static void packet_cached_dev_assign(struct packet_sock *po,
254 struct net_device *dev)
255{
256 rcu_assign_pointer(po->cached_dev, dev);
257}
258
259static void packet_cached_dev_reset(struct packet_sock *po)
260{
261 RCU_INIT_POINTER(po->cached_dev, NULL);
262}
263
240/* register_prot_hook must be invoked with the po->bind_lock held, 264/* register_prot_hook must be invoked with the po->bind_lock held,
241 * or from a context in which asynchronous accesses to the packet 265 * or from a context in which asynchronous accesses to the packet
242 * socket is not possible (packet_create()). 266 * socket is not possible (packet_create()).
@@ -246,12 +270,10 @@ static void register_prot_hook(struct sock *sk)
246 struct packet_sock *po = pkt_sk(sk); 270 struct packet_sock *po = pkt_sk(sk);
247 271
248 if (!po->running) { 272 if (!po->running) {
249 if (po->fanout) { 273 if (po->fanout)
250 __fanout_link(sk, po); 274 __fanout_link(sk, po);
251 } else { 275 else
252 dev_add_pack(&po->prot_hook); 276 dev_add_pack(&po->prot_hook);
253 rcu_assign_pointer(po->cached_dev, po->prot_hook.dev);
254 }
255 277
256 sock_hold(sk); 278 sock_hold(sk);
257 po->running = 1; 279 po->running = 1;
@@ -270,12 +292,11 @@ static void __unregister_prot_hook(struct sock *sk, bool sync)
270 struct packet_sock *po = pkt_sk(sk); 292 struct packet_sock *po = pkt_sk(sk);
271 293
272 po->running = 0; 294 po->running = 0;
273 if (po->fanout) { 295
296 if (po->fanout)
274 __fanout_unlink(sk, po); 297 __fanout_unlink(sk, po);
275 } else { 298 else
276 __dev_remove_pack(&po->prot_hook); 299 __dev_remove_pack(&po->prot_hook);
277 RCU_INIT_POINTER(po->cached_dev, NULL);
278 }
279 300
280 __sock_put(sk); 301 __sock_put(sk);
281 302
@@ -2048,19 +2069,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
2048 return tp_len; 2069 return tp_len;
2049} 2070}
2050 2071
2051static struct net_device *packet_cached_dev_get(struct packet_sock *po)
2052{
2053 struct net_device *dev;
2054
2055 rcu_read_lock();
2056 dev = rcu_dereference(po->cached_dev);
2057 if (dev)
2058 dev_hold(dev);
2059 rcu_read_unlock();
2060
2061 return dev;
2062}
2063
2064static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) 2072static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2065{ 2073{
2066 struct sk_buff *skb; 2074 struct sk_buff *skb;
@@ -2077,7 +2085,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2077 2085
2078 mutex_lock(&po->pg_vec_lock); 2086 mutex_lock(&po->pg_vec_lock);
2079 2087
2080 if (saddr == NULL) { 2088 if (likely(saddr == NULL)) {
2081 dev = packet_cached_dev_get(po); 2089 dev = packet_cached_dev_get(po);
2082 proto = po->num; 2090 proto = po->num;
2083 addr = NULL; 2091 addr = NULL;
@@ -2231,7 +2239,7 @@ static int packet_snd(struct socket *sock,
2231 * Get and verify the address. 2239 * Get and verify the address.
2232 */ 2240 */
2233 2241
2234 if (saddr == NULL) { 2242 if (likely(saddr == NULL)) {
2235 dev = packet_cached_dev_get(po); 2243 dev = packet_cached_dev_get(po);
2236 proto = po->num; 2244 proto = po->num;
2237 addr = NULL; 2245 addr = NULL;
@@ -2440,6 +2448,8 @@ static int packet_release(struct socket *sock)
2440 2448
2441 spin_lock(&po->bind_lock); 2449 spin_lock(&po->bind_lock);
2442 unregister_prot_hook(sk, false); 2450 unregister_prot_hook(sk, false);
2451 packet_cached_dev_reset(po);
2452
2443 if (po->prot_hook.dev) { 2453 if (po->prot_hook.dev) {
2444 dev_put(po->prot_hook.dev); 2454 dev_put(po->prot_hook.dev);
2445 po->prot_hook.dev = NULL; 2455 po->prot_hook.dev = NULL;
@@ -2495,14 +2505,17 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc
2495 2505
2496 spin_lock(&po->bind_lock); 2506 spin_lock(&po->bind_lock);
2497 unregister_prot_hook(sk, true); 2507 unregister_prot_hook(sk, true);
2508
2498 po->num = protocol; 2509 po->num = protocol;
2499 po->prot_hook.type = protocol; 2510 po->prot_hook.type = protocol;
2500 if (po->prot_hook.dev) 2511 if (po->prot_hook.dev)
2501 dev_put(po->prot_hook.dev); 2512 dev_put(po->prot_hook.dev);
2502 po->prot_hook.dev = dev;
2503 2513
2514 po->prot_hook.dev = dev;
2504 po->ifindex = dev ? dev->ifindex : 0; 2515 po->ifindex = dev ? dev->ifindex : 0;
2505 2516
2517 packet_cached_dev_assign(po, dev);
2518
2506 if (protocol == 0) 2519 if (protocol == 0)
2507 goto out_unlock; 2520 goto out_unlock;
2508 2521
@@ -2615,7 +2628,8 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
2615 po = pkt_sk(sk); 2628 po = pkt_sk(sk);
2616 sk->sk_family = PF_PACKET; 2629 sk->sk_family = PF_PACKET;
2617 po->num = proto; 2630 po->num = proto;
2618 RCU_INIT_POINTER(po->cached_dev, NULL); 2631
2632 packet_cached_dev_reset(po);
2619 2633
2620 sk->sk_destruct = packet_sock_destruct; 2634 sk->sk_destruct = packet_sock_destruct;
2621 sk_refcnt_debug_inc(sk); 2635 sk_refcnt_debug_inc(sk);
@@ -3369,6 +3383,7 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void
3369 sk->sk_error_report(sk); 3383 sk->sk_error_report(sk);
3370 } 3384 }
3371 if (msg == NETDEV_UNREGISTER) { 3385 if (msg == NETDEV_UNREGISTER) {
3386 packet_cached_dev_reset(po);
3372 po->ifindex = -1; 3387 po->ifindex = -1;
3373 if (po->prot_hook.dev) 3388 if (po->prot_hook.dev)
3374 dev_put(po->prot_hook.dev); 3389 dev_put(po->prot_hook.dev);