Re: [PATCH net 1/1] xdp: reject clones that overrun skb_shared_info tailroom
zhilin zou <[email protected]> Tue, 4 Aug 2026 20:54:07 +0800
| Newsgroups | org.kernel.vger.bpf,dev.linux.lists.sashiko-reviews |
|---|---|
| Message-ID | <CANB6i5yoK8dV0y8BXDaFFVQ--TkMztrFkFDxtPsGRD+DjTsVXA@mail.gmail.com> |
On Tue, Aug 4, 2026 at 8:16=E2=80=AFPM <[email protected]> wrote: > > Thank you for your contribution! Sashiko AI review found 3 potential issu= e(s) to consider: > > Pre-existing issues: > - [High] Missing SKB_WITH_OVERHEAD check in `xdp_convert_zc_to_xdp_frame(= )` leads to in-page overwrite of packet data with `skb_shared_info`. > - [High] Incorrect `headroom` initialization in `xdp_convert_zc_to_xdp_fr= ame()` causes an out-of-bounds write of `skb_shared_info` into the next phy= sical page. > - [High] Silently dropping packet fragments in `xdp_convert_zc_to_xdp_fra= me()` causes truncation of multi-buffer packets. > -- > > --- Patch [1]: [PATCH net 1/1] xdp: reject clones that overrun skb_shared= _info tailroom --- > commit 06453b67e02a5370da9d6643a102dd0628f4807c > Author: Zhiling Zou <[email protected]> > > xdp: reject clones that overrun skb_shared_info tailroom > > This commit updates xdpf_clone() to reject frames that do not leave > enough room for skb_shared_info. It changes the bounds check to use > SKB_WITH_OVERHEAD(PAGE_SIZE) to prevent build_skb_around() from > corrupting live packet bytes during XDP-to-SKB conversion. > > > diff --git a/net/core/xdp.c b/net/core/xdp.c > > index 9890a30584ba7..0194e69da339a 100644 > > --- a/net/core/xdp.c > > +++ b/net/core/xdp.c > > @@ -871,7 +871,7 @@ struct xdp_frame *xdpf_clone(struct xdp_frame *xdpf= ) > > headroom =3D xdpf->headroom + sizeof(*xdpf); > > totalsize =3D headroom + xdpf->len; > > > > - if (unlikely(totalsize > PAGE_SIZE)) > > + if (unlikely(totalsize > SKB_WITH_OVERHEAD(PAGE_SIZE))) > > return NULL; > > page =3D dev_alloc_page(); > > if (!page) > > Looking at the fix applied here, there appear to be similar pre-existing > issues in the same file within xdp_convert_zc_to_xdp_frame(): > > net/core/xdp.c:xdp_convert_zc_to_xdp_frame() { > metasize =3D xdp_data_meta_unsupported(xdp) ? 0 : > xdp->data - xdp->data_meta; > totsize =3D xdp->data_end - xdp->data + metasize; > > [Severity: High] > This isn't a bug introduced by this patch, but does this calculation > result in silently dropped packet fragments? > > If an AF_XDP multi-buffer zero-copy packet with XDP_FLAGS_HAS_FRAGS set i= s > passed here, only the linear data size is calculated. The fragments appea= r > to be ignored, and the original xdp_buff is freed back to the pool, > returning a truncated xdp_frame without propagating the fragments. > > if (sizeof(*xdpf) + totsize > PAGE_SIZE) > return NULL; > > [Severity: High] > This is a pre-existing issue, but should this bounds check also use > SKB_WITH_OVERHEAD(PAGE_SIZE) similar to the fix in xdpf_clone()? > > If an AF_XDP zero-copy packet has a linear length between > SKB_WITH_OVERHEAD(PAGE_SIZE) and PAGE_SIZE, it will pass this check. > When __xdp_build_skb_from_frame() later converts this frame into an SKB, > build_skb_around() could overwrite the valid packet payload with > skb_shared_info. > > addr +=3D sizeof(*xdpf); > data_to_copy =3D metasize ? xdp->data_meta : xdp->data; > memcpy(addr, data_to_copy, totsize); > > xdpf->data =3D addr + metasize; > xdpf->len =3D totsize - metasize; > xdpf->headroom =3D 0; > > [Severity: High] > This isn't a bug introduced by this patch, but could setting headroom to = 0 > instead of metasize cause an out-of-bounds write? > > If metasize is greater than 0, setting headroom to 0 shifts the computed > hard_start of the SKB buffer forward by metasize bytes. When > build_skb_around() is called on this buffer with a length of PAGE_SIZE, > the buffer logically extends past the allocated page boundary. > > If fragments are later appended or the tailroom is used, could the stack > write directly into the next physical page? > } > > -- > Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/6b2afef5d1738763c= [email protected]?part=3D1 Thanks for the review. The reported issues are not introduced by this patch. This patch is limited to the reproduced devmap broadcast clone path in xdpf_clone(), where the cl= one is copied into a single page and can later be converted to an skb without reserved skb_shared_info tailroom. I agree that xdp_convert_zc_to_xdp_frame() looks like a similar pre-existin= g area worth auditing separately: it also clones into a PAGE_ORDER0 xdp_frame and sets frame_sz to PAGE_SIZE. The SKB_WITH_OVERHEAD() bound and the metadata/headroom handling there need separate validation because that path= is for XSK zero-copy conversion, not the devmap broadcast clone path fixed her= e. For the fragment point, I would like to verify the reachable path first. If= a fragmented XSK zero-copy xdp_buff can reach xdp_convert_zc_to_xdp_frame(), then preserving or rejecting frags should be handled in a follow-up fix. So I would prefer to keep this patch focused on the confirmed xdpf_clone() bug, and handle xdp_convert_zc_to_xdp_frame() as a separate follow-up after checking reachability and reproducing it.