Re: [net-next,v2,3/6] net: bcmgenet: add basic XDP support (PASS/DROP)

From: Nicolai Buchwitz

Date: Tue Mar 17 2026 - 15:28:11 EST


On 17.3.2026 17:19, Simon Horman wrote:
[...]


+static struct sk_buff *bcmgenet_xdp_build_skb(struct bcmgenet_rx_ring *ring,
+ struct xdp_buff *xdp,
+ struct page *rx_page)
+{
+ unsigned int metasize;
+ struct sk_buff *skb;
+
+ skb = napi_build_skb(xdp->data_hard_start, PAGE_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ skb_mark_for_recycle(skb);
+
+ metasize = xdp->data - xdp->data_meta;
+ skb_reserve(skb, xdp->data - xdp->data_hard_start);
+ __skb_put(skb, xdp->data_end - xdp->data);
+
+ if (metasize)
+ skb_metadata_set(skb, metasize);
^^^^

Can this corrupt memory? Looking at bcmgenet_desc_rx(), the xdp_buff is
initialized with meta_valid=false:

xdp_prepare_buff(&xdp, page_address(rx_page),
GENET_RX_HEADROOM, pkt_len, false);

When meta_valid is false, xdp_prepare_buff() sets xdp->data_meta to
xdp->data + 1 as a sentinel value to indicate no metadata is present.

In bcmgenet_xdp_build_skb(), the metasize calculation becomes:

metasize = xdp->data - xdp->data_meta
= xdp->data - (xdp->data + 1)
= (ptrdiff_t)-1

When assigned to 'unsigned int metasize', this wraps to UINT_MAX. The
'if (metasize)' check passes since UINT_MAX != 0, and
skb_metadata_set(skb, metasize) truncates UINT_MAX to u8, setting
skb_shinfo(skb)->meta_len = 255.

This incorrect meta_len of 255 can cause downstream SKB consumers (TC BPF
programs, skb_data_move) to read or write 255 bytes before
skb_mac_header(skb) when accessing the metadata region.

Other XDP drivers that use skb_metadata_set() (bnxt, mvneta, ixgbe,
i40e, virtio_net) all pass meta_valid=true to xdp_prepare_buff(), which
sets data_meta=data, giving metasize=0 and correctly skipping
skb_metadata_set().

Should xdp_prepare_buff() be called with meta_valid=true instead of
false, since bcmgenet_xdp_build_skb() handles XDP metadata?

Will fix this in v3 by passing meta_valid=true, matching what other XDP
drivers do.

Thanks
Nicolai

[...]