Skip to content

Commit

Permalink
ping: Fix race in free in receive path
Browse files Browse the repository at this point in the history
An exception is seen in ICMP ping receive path where the skb
destructor sock_rfree() tries to access a freed socket. This happens
because ping_rcv() releases socket reference with sock_put() and this
internally frees up the socket. Later icmp_rcv() will try to free the
skb and as part of this, skb destructor is called and which leads
to a kernel panic as the socket is freed already in ping_rcv().

-->|exception
-007|sk_mem_uncharge
-007|sock_rfree
-008|skb_release_head_state
-009|skb_release_all
-009|__kfree_skb
-010|kfree_skb
-011|icmp_rcv
-012|ip_local_deliver_finish

Fix this incorrect free by cloning this skb and processing this cloned
skb instead.

This patch was suggested by Eric Dumazet

Signed-off-by: Subash Abhinov Kasiviswanathan <[email protected]>
Cc: Eric Dumazet <[email protected]>
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
[email protected] authored and davem330 committed Jan 27, 2015
1 parent 86f3cdd commit fc752f1
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion net/ipv4/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -966,8 +966,11 @@ bool ping_rcv(struct sk_buff *skb)

sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id));
if (sk != NULL) {
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);

pr_debug("rcv on socket %p\n", sk);
ping_queue_rcv_skb(sk, skb_get(skb));
if (skb2)
ping_queue_rcv_skb(sk, skb2);
sock_put(sk);
return true;
}
Expand Down

0 comments on commit fc752f1

Please sign in to comment.