mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
xsk: prevent CQ desync when freeing half-built skbs in xsk_build_skb()
Once xsk_skb_init_misc() has been called on an skb, its destructor is
set to xsk_destruct_skb(), which submits the descriptor address(es) to
the completion queue and advances the CQ producer. If such an skb is
subsequently freed via kfree_skb() along an error path - before the
skb has ever been handed to the driver - the destructor still runs and
submits a bogus, half-initialized address to the CQ.
Postpone the init phase when we believe the allocation of first frag is
successfully completed. Before this init, skb can be safely freed by
kfree_skb().
Closes: https://lore.kernel.org/all/20260419045822.843BFC2BCAF@smtp.kernel.org/
Fixes: c30d084960 ("xsk: avoid overwriting skb fields for multi-buffer traffic")
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Signed-off-by: Jason Xing <kernelxing@tencent.com>
Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Link: https://patch.msgid.link/20260502200722.53960-6-kerneljasonxing@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
0f3776583d
commit
3dec153ae4
|
|
@ -819,8 +819,6 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
|
|||
return ERR_PTR(err);
|
||||
|
||||
skb_reserve(skb, hr);
|
||||
|
||||
xsk_skb_init_misc(skb, xs, desc->addr);
|
||||
if (desc->options & XDP_TX_METADATA) {
|
||||
err = xsk_skb_metadata(skb, buffer, desc, pool, hr);
|
||||
if (unlikely(err))
|
||||
|
|
@ -917,7 +915,6 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
|
|||
if (unlikely(err))
|
||||
goto free_err;
|
||||
|
||||
xsk_skb_init_misc(skb, xs, desc->addr);
|
||||
if (desc->options & XDP_TX_METADATA) {
|
||||
err = xsk_skb_metadata(skb, buffer, desc,
|
||||
xs->pool, hr);
|
||||
|
|
@ -967,6 +964,8 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
|
|||
}
|
||||
}
|
||||
|
||||
if (!xs->skb)
|
||||
xsk_skb_init_misc(skb, xs, desc->addr);
|
||||
xsk_inc_num_desc(skb);
|
||||
|
||||
return skb;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user