[PATCH] iptables: fix null dereference parsing bitwise operations

Remy D. Farley
2026-02-12T19:34:40Z

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.

>
> Thanks, Phil