From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Omkhar Arasaratnam <omkhar@linkedin.com>
Cc: "netfilter-devel@vger.kernel.org"
<netfilter-devel@vger.kernel.org>, "phil@nwl.cc" <phil@nwl.cc>,
"fw@strlen.de" <fw@strlen.de>
Subject: Re: [PATCH iptables] nft: bridge: fix among buffer overflow when set has no size
Date: Fri, 31 Jul 2026 13:33:12 +0200 [thread overview]
Message-ID: <amyH-DnOnds5cOAf@chamomile> (raw)
In-Reply-To: <LV0SPRMB0026C00DF7CAE003665E672FA1C62@LV0SPRMB0026.namprd21.prod.outlook.com>
On Fri, Jul 17, 2026 at 06:56:58PM +0000, Omkhar Arasaratnam wrote:
> The among match parser sizes its pair buffer from NFTNL_SET_DESC_SIZE:
>
> cnt = nftnl_set_get_u32(s, NFTNL_SET_DESC_SIZE);
> ...
> size = cnt * sizeof(struct nft_among_pair);
> match->m = xtables_calloc(1, size);
> ...
> set_elems_to_among_pairs(among_data->pairs + poff, s, cnt);
>
> NFTNL_SET_DESC_SIZE is the hash-table size hint, which is only present
> when the set was created with an explicit "size". A set created without
> one (e.g. via plain nft: add set bridge filter s { type ether_addr; })
> carries no NFTA_SET_DESC_SIZE, so nftnl_set_get_u32() returns 0. The
> buffer is then allocated header-only while set_elems_to_among_pairs()
> still walks every element of the set and writes one nft_among_pair each,
> overflowing the allocation on the first element. Listing such a ruleset
> with ebtables-nft -L (or ebtables-nft-restore) corrupts the heap.
I assume this is triggered by a crafted set not created by iptables-nft.
Fortify instead set_elems_to_among_pairs() so it does not crash
instead.
> Size the buffer from the actual number of set elements instead, i.e.
> exactly what set_elems_to_among_pairs() iterates over. Sets created by
> the among match itself are unaffected: their element count equals the
> NFTNL_SET_DESC_SIZE that was used before.
>
> Fixes: 26753888720d ("nft: bridge: Rudimental among extension support")
> Signed-off-by: Omkhar Arasaratnam <omkhar@linkedin.com>
> ---
> iptables/nft-ruleparse-bridge.c | 22 +++++++++++++++++++++-
> 1 file changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/iptables/nft-ruleparse-bridge.c b/iptables/nft-ruleparse-bridge.c
> index aee08b13..fc877d43 100644
> --- a/iptables/nft-ruleparse-bridge.c
> +++ b/iptables/nft-ruleparse-bridge.c
> @@ -306,6 +306,23 @@ static struct nftnl_set *set_from_lookup_expr(struct nft_xt_ctx *ctx,
> return NULL;
> }
>
> +static uint32_t set_elem_count(const struct nftnl_set *s)
> +{
> + struct nftnl_set_elems_iter *iter = nftnl_set_elems_iter_create(s);
> + uint32_t cnt = 0;
> +
> + if (!iter)
> + xtables_error(OTHER_PROBLEM,
> + "BUG: set elems iter allocation failed");
> +
> + while (nftnl_set_elems_iter_next(iter))
> + cnt++;
> +
> + nftnl_set_elems_iter_destroy(iter);
> +
> + return cnt;
> +}
> +
> static void nft_bridge_parse_lookup(struct nft_xt_ctx *ctx,
> struct nftnl_expr *e)
> {
> @@ -328,7 +345,10 @@ static void nft_bridge_parse_lookup(struct nft_xt_ctx *ctx,
> &is_dst, &have_ip))
> return;
>
> - cnt = nftnl_set_get_u32(s, NFTNL_SET_DESC_SIZE);
> + /* NFTNL_SET_DESC_SIZE is unset for sets without an explicit size, so
> + * count the actual elements instead of trusting it.
> + */
> + cnt = set_elem_count(s);
>
> for (ematch = ctx->cs->match_list; ematch; ematch = ematch->next) {
> if (!ematch->ismatch || strcmp(ematch->u.match->name, "among"))
> --
> 2.34.1
>
> — oa
prev parent reply other threads:[~2026-07-31 11:33 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-17 18:56 [PATCH iptables] nft: bridge: fix among buffer overflow when set has no size Omkhar Arasaratnam
2026-07-31 11:33 ` Pablo Neira Ayuso [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=amyH-DnOnds5cOAf@chamomile \
--to=pablo@netfilter.org \
--cc=fw@strlen.de \
--cc=netfilter-devel@vger.kernel.org \
--cc=omkhar@linkedin.com \
--cc=phil@nwl.cc \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.