Re: [PATCH] iptables: fix null dereference parsing bitwise operations

Phil Sutter
2026-02-13T13:06:06Z

On Thu, Feb 12, 2026 at 07:34:29PM +0000, Remy D. Farley wrote:
> On Wednesday, February 11th, 2026 at 21:37, Phil Sutter <phil@nwl.cc> wrote:
>
> > On Mon, Feb 02, 2026 at 10:14:52AM +0000, Remy D. Farley wrote:
> > > diff --git a/iptables/nft-ruleparse.c b/iptables/nft-ruleparse.c
> > > index cdf1af4f..1a9084e3 100644
> > > --- a/iptables/nft-ruleparse.c
> > > +++ b/iptables/nft-ruleparse.c
> > > @@ -232,6 +232,11 @@ static void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
> > > const void *data;
> > > uint32_t len;
> > >
> > > + if (nftnl_expr_get_u32(e, NFTNL_EXPR_BITWISE_OP) != 0 /* empty or MASK_XOR */) {
> > > + ctx->errmsg = "unsupported bitwise operation";
> > > + return;
> > > + }
> > > +
> >
> > This is redundant wrt. the stricter compatibility check below, right? Or
> > did you find a call to nft_rule_to_iptables_command_state() which is not
> > guarded by nft_is_table_compatible()?
>
>
> Yeah, I wasn't sure that was the case. I'll remove this check.
>
>
> > Anyway, I would add two checks to that function like so:
> >
> > | if (!data) {
> > | ctx->errmsg = "missing bitwise xor attribute";
> > | return;
> > | }
> >
> > (And the same for bitwise mask.) It will sanitize the function's code
> > irrespective of expression content, readers won't have to be aware of
> > (and rely upon) bitwise expression semantics with NFTNL_EXPR_BITWISE_OP
> > attribute value being zero.
> >
> > > if (!sreg)
> > > return;
> > >
> > > diff --git a/iptables/nft.c b/iptables/nft.c
> > > index 85080a6d..661fac29 100644
> > > --- a/iptables/nft.c
> > > +++ b/iptables/nft.c
> > > @@ -4029,7 +4029,6 @@ static const char *supported_exprs[] = {
> > > "payload",
> > > "meta",
> > > "cmp",
> > > - "bitwise",
> > > "counter",
> > > "immediate",
> > > "lookup",
> > > @@ -4056,6 +4055,10 @@ static int nft_is_expr_compatible(struct nftnl_expr *expr, void *data)
> > > nftnl_expr_is_set(expr, NFTNL_EXPR_LOG_GROUP))
> > > return 0;
> > >
> > > + if (!strcmp(name, "bitwise") &&
> > > + nftnl_expr_get_u32(expr, NFTNL_EXPR_BITWISE_OP) == 0 /* empty or MASK_XOR */)
> >
> > '== NFT_BITWISE_MASK_XOR' and drop the comment.
>
>
> It took me a while to realize iptables/linux headers are quite outdated,
> so NFT_BITWISE_MASK_XOR is still called NFT_BITWISE_BOOL in there.

Ah, sorry about that. I merely looked at current kernel headers to check
if that magic zero could be replaced by something more descriptive.

Cheers, Phil