Skip to content

Commit ca2c141

Browse files
Paolo Abenidavem330
authored andcommitted
udp: drop head states only when all skb references are gone
After commit 0ddf3fb ("udp: preserve skb->dst if required for IP options processing") we clear the skb head state as soon as the skb carrying them is first processed. Since the same skb can be processed several times when MSG_PEEK is used, we can end up lacking the required head states, and eventually oopsing. Fix this clearing the skb head state only when processing the last skb reference. Reported-by: Eric Dumazet <edumazet@google.com> Fixes: 0ddf3fb ("udp: preserve skb->dst if required for IP options processing") Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 5c25f30 commit ca2c141

File tree

3 files changed

+8
-8
lines changed

3 files changed

+8
-8
lines changed

include/linux/skbuff.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ void kfree_skb(struct sk_buff *skb);
958958
void kfree_skb_list(struct sk_buff *segs);
959959
void skb_tx_error(struct sk_buff *skb);
960960
void consume_skb(struct sk_buff *skb);
961-
void consume_stateless_skb(struct sk_buff *skb);
961+
void __consume_stateless_skb(struct sk_buff *skb);
962962
void __kfree_skb(struct sk_buff *skb);
963963
extern struct kmem_cache *skbuff_head_cache;
964964

net/core/skbuff.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -710,14 +710,11 @@ EXPORT_SYMBOL(consume_skb);
710710
* consume_stateless_skb - free an skbuff, assuming it is stateless
711711
* @skb: buffer to free
712712
*
713-
* Works like consume_skb(), but this variant assumes that all the head
714-
* states have been already dropped.
713+
* Alike consume_skb(), but this variant assumes that this is the last
714+
* skb reference and all the head states have been already dropped
715715
*/
716-
void consume_stateless_skb(struct sk_buff *skb)
716+
void __consume_stateless_skb(struct sk_buff *skb)
717717
{
718-
if (!skb_unref(skb))
719-
return;
720-
721718
trace_consume_skb(skb);
722719
skb_release_data(skb);
723720
kfree_skbmem(skb);

net/ipv4/udp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1397,12 +1397,15 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
13971397
unlock_sock_fast(sk, slow);
13981398
}
13991399

1400+
if (!skb_unref(skb))
1401+
return;
1402+
14001403
/* In the more common cases we cleared the head states previously,
14011404
* see __udp_queue_rcv_skb().
14021405
*/
14031406
if (unlikely(udp_skb_has_head_state(skb)))
14041407
skb_release_head_state(skb);
1405-
consume_stateless_skb(skb);
1408+
__consume_stateless_skb(skb);
14061409
}
14071410
EXPORT_SYMBOL_GPL(skb_consume_udp);
14081411

0 commit comments

Comments
 (0)