From: Florian Westphal Date: Mon, 13 Apr 2026 04:32:47 +0000 (+0000) Subject: netfilter: nft_set_pipapo: do not rely on ZERO_SIZE_PTR X-Git-Tag: v6.1.169~22 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a4983e89e3b1ce0234df9ad35017120fe39f6ea0;p=thirdparty%2Fkernel%2Fstable.git netfilter: nft_set_pipapo: do not rely on ZERO_SIZE_PTR commit 07ace0bbe03b3d8e85869af1dec5e4087b1d57b8 upstream pipapo relies on kmalloc(0) returning ZERO_SIZE_PTR (i.e., not NULL but pointer is invalid). Rework this to not call slab allocator when we'd request a 0-byte allocation. Reviewed-by: Stefano Brivio Signed-off-by: Florian Westphal Signed-off-by: Mukul Sikka Signed-off-by: Brennan Lamoreaux [Keerthana: In older stable branches (v6.6 and earlier), the allocation logic in pipapo_clone() still relies on `src->rules` rather than `src->rules_alloc` (introduced in v6.9 via 9f439bd6ef4f). Consequently, the previously backported INT_MAX clamping check uses `src->rules`. This patch correctly moves that `src->rules > (INT_MAX / ...)` check inside the new `if (src->rules > 0)` block] Signed-off-by: Keerthana K Signed-off-by: Greg Kroah-Hartman --- diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c index 673d73dce3883..cfd0d020f3382 100644 --- a/net/netfilter/nft_set_pipapo.c +++ b/net/netfilter/nft_set_pipapo.c @@ -525,6 +525,8 @@ static struct nft_pipapo_elem *pipapo_get(const struct net *net, int i; m = priv->clone; + if (m->bsize_max == 0) + return ret; res_map = kmalloc_array(m->bsize_max, sizeof(*res_map), GFP_ATOMIC); if (!res_map) { @@ -1395,14 +1397,20 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old) src->bsize * sizeof(*dst->lt) * src->groups * NFT_PIPAPO_BUCKETS(src->bb)); - if (src->rules > (INT_MAX / sizeof(*src->mt))) - goto out_mt; + if (src->rules > 0) { + if (src->rules > (INT_MAX / sizeof(*src->mt))) + goto out_mt; + + dst->mt = kvmalloc_array(src->rules, sizeof(*src->mt), + GFP_KERNEL); + if (!dst->mt) + goto out_mt; - dst->mt = kvmalloc(src->rules * sizeof(*src->mt), GFP_KERNEL_ACCOUNT); - if (!dst->mt) - goto out_mt; + memcpy(dst->mt, src->mt, src->rules * sizeof(*src->mt)); + } else { + dst->mt = NULL; + } - memcpy(dst->mt, src->mt, src->rules * sizeof(*src->mt)); src++; dst++; }