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: fix out-of-bounds read listing an old-revision match
Date: Fri, 31 Jul 2026 13:37:10 +0200 [thread overview]
Message-ID: <amyI5pPa_4a7v2VP@chamomile> (raw)
In-Reply-To: <LV0SPRMB0026AFC6E85D19E90A2C3CBAA1C62@LV0SPRMB0026.namprd21.prod.outlook.com>
On Fri, Jul 17, 2026 at 06:59:27PM +0000, Omkhar Arasaratnam wrote:
> nft_parse_match() sizes the xt_entry_match buffer from the wire blob
> length reported by the kernel:
>
> m = xtables_calloc(1, sizeof(struct xt_entry_match) + mt_len);
> memcpy(&m->data, mt_info, mt_len);
>
> but selects the print/save/compare extension purely by name via
> xtables_find_match(), which returns the highest supported revision. When
> the kernel stored an older, smaller revision of the match, mt_len is
> smaller than the resolved extension's userspacesize, and the print
> callback -- and compare_matches(), which memcmp()s userspacesize bytes
> -- read past the mt_len-sized allocation.
>
> For example a conntrack match stored as xt_conntrack_mtinfo1 (152 bytes)
> is printed by the rev3 callback conntrack_dump(), which reads
> xt_conntrack_mtinfo3 fields (info->origsrc_port_high at offset 154), two
> bytes past the buffer. Listing such a ruleset with iptables-nft -L reads
> out of bounds.
Is this a hypothetical crash? How can this happen in practise? These
revisions are very old, you would need to pick a very old iptables
version which possibly does not supports nftables to trigger this?
> Size the allocation to the resolved extension when its blob is larger,
> just as nft_create_match() and __nft_create_target() already do, so the
> print and compare paths stay in bounds. Matches whose stored blob is at
> least as large as the extension are unaffected.
>
> Fixes: cdc78b1d6bd7 ("nft: convert rule into a command state structure")
> Signed-off-by: Omkhar Arasaratnam <omkhar@linkedin.com>
> ---
> iptables/nft-ruleparse.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/iptables/nft-ruleparse.c b/iptables/nft-ruleparse.c
> index 26a605cf..2c5aa9ce 100644
> --- a/iptables/nft-ruleparse.c
> +++ b/iptables/nft-ruleparse.c
> @@ -638,7 +638,10 @@ static void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
> return;
> }
>
> - m = xtables_calloc(1, sizeof(struct xt_entry_match) + mt_len);
> + /* Kernel blob may be smaller than the resolved extension (older
> + * revision); size to the extension so print/compare stay in bounds. */
> + m = xtables_calloc(1, sizeof(struct xt_entry_match) +
> + (mt_len < match->size ? match->size : mt_len));
> memcpy(&m->data, mt_info, mt_len);
> m->u.match_size = mt_len + XT_ALIGN(sizeof(struct xt_entry_match));
> m->u.user.revision = nftnl_expr_get_u32(e, NFTNL_EXPR_TG_REV);
> --
> 2.34.1
prev parent reply other threads:[~2026-07-31 11:37 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-17 18:59 [PATCH iptables] nft: fix out-of-bounds read listing an old-revision match Omkhar Arasaratnam
2026-07-31 11:37 ` 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=amyI5pPa_4a7v2VP@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox