summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Xing <kernelxing@tencent.com>2026-05-02 23:07:17 +0300
committerJakub Kicinski <kuba@kernel.org>2026-05-05 19:27:50 -0700
commit8cd3c1c6e7d9a1f0954159ec5f2fdaa7f6a48bd8 (patch)
treea78e7f9775e61c70cde03b0170afe794d7bfdb99
parent0bb7a9caf5c1d6e25ba376ea6b39261ad28550f4 (diff)
downloadlinux-next-8cd3c1c6e7d9a1f0954159ec5f2fdaa7f6a48bd8.tar.gz
linux-next-8cd3c1c6e7d9a1f0954159ec5f2fdaa7f6a48bd8.zip
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: cf24f5a5feea ("xsk: add support for AF_XDP multi-buffer on Tx path") 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-4-kerneljasonxing@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--net/xdp/xsk.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index d706b1e0bf60..06ee260f3afc 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -976,9 +976,14 @@ free_err:
kfree_skb(skb);
if (err == -EOVERFLOW) {
- /* Drop the packet */
- xsk_inc_num_desc(xs->skb);
- xsk_drop_skb(xs->skb);
+ 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 */