Commit 8cd3c1c6 authored by Jason Xing's avatar Jason Xing Committed by Jakub Kicinski
Browse files

xsk: handle NULL dereference of the skb without frags issue



When a first descriptor (xs->skb == NULL) triggers -EOVERFLOW in
xsk_build_skb_zerocopy() (e.g., MAX_SKB_FRAGS exceeded), the
free_err -EOVERFLOW handler unconditionally dereferences xs->skb
via xsk_inc_num_desc(xs->skb) and xsk_drop_skb(xs->skb), causing
a NULL pointer dereference.

Fix this by guarding the existing xsk_inc_num_desc()/xsk_drop_skb()
calls with an xs->skb check (for the continuation case), and add
an else branch for the first-descriptor case that manually cancels
the one reserved CQ slot and increments invalid_descs by one to
account for the single invalid descriptor.

Fixes: cf24f5a5 ("xsk: add support for AF_XDP multi-buffer on Tx path")
Acked-by: default avatarStanislav Fomichev <sdf@fomichev.me>
Signed-off-by: default avatarJason Xing <kernelxing@tencent.com>
Reviewed-by: default avatarAlexander Lobakin <aleksander.lobakin@intel.com>
Link: https://patch.msgid.link/20260502200722.53960-4-kerneljasonxing@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 0bb7a9ca
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -976,9 +976,14 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
		kfree_skb(skb);

	if (err == -EOVERFLOW) {
		if (xs->skb) {
			/* Drop the packet */
			xsk_inc_num_desc(xs->skb);
			xsk_drop_skb(xs->skb);
		} else {
			xsk_cq_cancel_locked(xs->pool, 1);
			xs->tx->invalid_descs++;
		}
		xskq_cons_release(xs->tx);
	} else {
		/* Let application retry */