Skip to content

Commit 0c0d0f4

Browse files
fmaurer-rhkuba-moo
authored andcommitted
xsk: Free skb when TX metadata options are invalid
When a new skb is allocated for transmitting an xsk descriptor, i.e., for every non-multibuf descriptor or the first frag of a multibuf descriptor, but the descriptor is later found to have invalid options set for the TX metadata, the new skb is never freed. This can leak skbs until the send buffer is full which makes sending more packets impossible. Fix this by freeing the skb in the error path if we are currently dealing with the first frag, i.e., an skb allocated in this iteration of xsk_build_skb. Fixes: 48eb03d ("xsk: Add TX timestamp and TX checksum offload support") Reported-by: Michal Schmidt <[email protected]> Signed-off-by: Felix Maurer <[email protected]> Reviewed-by: Toke Høiland-Jørgensen <[email protected]> Acked-by: Stanislav Fomichev <[email protected]> Acked-by: Martin KaFai Lau <[email protected]> Link: https://patch.msgid.link/edb9b00fb19e680dff5a3350cd7581c5927975a8.1731581697.git.fmaurer@redhat.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 8807850 commit 0c0d0f4

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

net/xdp/xsk.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,8 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
675675
len = desc->len;
676676

677677
if (!skb) {
678+
first_frag = true;
679+
678680
hr = max(NET_SKB_PAD, L1_CACHE_ALIGN(dev->needed_headroom));
679681
tr = dev->needed_tailroom;
680682
skb = sock_alloc_send_skb(&xs->sk, hr + len + tr, 1, &err);
@@ -685,12 +687,8 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
685687
skb_put(skb, len);
686688

687689
err = skb_store_bits(skb, 0, buffer, len);
688-
if (unlikely(err)) {
689-
kfree_skb(skb);
690+
if (unlikely(err))
690691
goto free_err;
691-
}
692-
693-
first_frag = true;
694692
} else {
695693
int nr_frags = skb_shinfo(skb)->nr_frags;
696694
struct page *page;
@@ -758,6 +756,9 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
758756
return skb;
759757

760758
free_err:
759+
if (first_frag && skb)
760+
kfree_skb(skb);
761+
761762
if (err == -EOVERFLOW) {
762763
/* Drop the packet */
763764
xsk_set_destructor_arg(xs->skb);

0 commit comments

Comments
 (0)