From: Weiming Shi Date: Thu, 21 May 2026 16:33:13 +0000 (-0700) Subject: tun: free page on build_skb failure in tun_xdp_one() X-Git-Tag: v7.1-rc6~27^2~34 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=aa8963fdce667a42fb7f0bdd2909fadcab02f9a8;p=thirdparty%2Fkernel%2Fstable.git tun: free page on build_skb failure in tun_xdp_one() When build_skb() fails in tun_xdp_one(), the function sets ret to -ENOMEM and jumps to the out label, which returns without freeing the page that vhost_net_build_xdp() allocated for the frame. As with the short-frame rejection path, tun_sendmsg() discards the per-buffer error and still returns total_len, so vhost_tx_batch() takes the success path and never frees the page. Each build_skb() failure in a batch leaks one page-frag chunk. Free the page before taking the error path, matching the put_page() the other error exits of tun_xdp_one() already perform. Fixes: 043d222f93ab ("tuntap: accept an array of XDP buffs through sendmsg()") Reported-by: Xiang Mei Signed-off-by: Weiming Shi Reviewed-by: Dongli Zhang Reviewed-by: Willem de Bruijn Link: https://patch.msgid.link/20260521163312.1479805-2-bestswngs@gmail.com Signed-off-by: Jakub Kicinski --- diff --git a/drivers/net/tun.c b/drivers/net/tun.c index f594360d66d6..9e7744eb57a3 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -2439,6 +2439,7 @@ static int tun_xdp_one(struct tun_struct *tun, build: skb = build_skb(xdp->data_hard_start, buflen); if (!skb) { + put_page(virt_to_head_page(xdp->data)); ret = -ENOMEM; goto out; }