* iptables: zero dereference parsing bitwise operations
@ 2025-10-10 21:16 Remy D. Farley
2025-10-11 13:58 ` Florian Westphal
0 siblings, 1 reply; 8+ messages in thread
From: Remy D. Farley @ 2025-10-10 21:16 UTC (permalink / raw)
To: netfilter-devel@vger.kernel.org
While messing around with manually encoding nftables expressions, I noticed
that iptables binary v1.8.11 segfaults with -L and -D <chain> options, if
there's a rule containing a bitwise operation of a type other than
mask-and-xor. As I understand, iptables and nft tools only generate rules with
mask-xor, though the kernel seems to happily accept other types as well.
For the reference:
> /**
> * enum nft_bitwise_ops - nf_tables bitwise operations
> *
> * @NFT_BITWISE_MASK_XOR: mask-and-xor operation used to implement NOT, AND, OR
> * and XOR boolean operations
> * @NFT_BITWISE_LSHIFT: left-shift operation \
> * @NFT_BITWISE_RSHIFT: right-shift operation |
> * @NFT_BITWISE_AND: and operation | These all seem affected
> * @NFT_BITWISE_OR: or operation |
> * @NFT_BITWISE_XOR: xor operation /
> */
Hooking up a debugger, it looks like nft_parse_bitwise() doesn't check type of
a bitwise operation, nor validate that it's attributes being used are present.
From iptables/nft-ruleparse.c:
> static void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
> {
> [...]
>
> data = nftnl_expr_get(e, NFTNL_EXPR_BITWISE_XOR, &len); // <-- this attribute may not be present
>
> if (len > sizeof(dreg->bitwise.xor)) {
> ctx->errmsg = "bitwise xor too large";
> return;
> }
>
> memcpy(dreg->bitwise.xor, data, len); // <-- zero dereference happens here
>
> data = nftnl_expr_get(e, NFTNL_EXPR_BITWISE_MASK, &len);
>
> if (len > sizeof(dreg->bitwise.mask)) {
> ctx->errmsg = "bitwise mask too large";
> return;
> }
>
> memcpy(dreg->bitwise.mask, data, len);
>
> dreg->bitwise.set = true;
>
> }
The bug can be reproduced with a rule created using newrule operation that
looks something like this:
> OpNewruleDoRequest {
> Table: "filter",
> Chain: "example-chain",
> Expressions: ExprListAttrs {
> Elem: ExprAttrs {
> Name: "payload",
> Data: Payload(
> ExprPayloadAttrs {
> Dreg: 1 [Reg1],
> Base: 1 [NetworkHeader],
> Offset: 12,
> Len: 4,
> },
> ),
> },
> Elem: ExprAttrs {
> Name: "bitwise",
> Data: Bitwise(
> ExprBitwiseAttrs {
> Sreg: 1,
> Dreg: 1,
> Len: 4,
> Op: 3 [And],
> Data: DataAttrs {
> Value: [ 255, 255, 255, 0 ],
> },
> },
> ),
> },
> Elem: ExprAttrs {
> Name: "cmp",
> Data: Cmp(
> ExprCmpAttrs {
> Sreg: 1,
> Op: 0 [Eq],
> Data: DataAttrs {
> Value: [ 1, 2, 3, 0 ],
> },
> },
> ),
> },
> Elem: ExprAttrs {
> Name: "immediate",
> Data: Immediate(
> ExprImmediateAttrs {
> Dreg: 0,
> Data: DataAttrs {
> Verdict: VerdictAttrs {
> Code: 1 [Accept],
> },
> },
> },
> ),
> },
> },
> },
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: iptables: zero dereference parsing bitwise operations
2025-10-10 21:16 iptables: zero dereference parsing bitwise operations Remy D. Farley
@ 2025-10-11 13:58 ` Florian Westphal
2025-10-11 20:15 ` Remy D. Farley
0 siblings, 1 reply; 8+ messages in thread
From: Florian Westphal @ 2025-10-11 13:58 UTC (permalink / raw)
To: Remy D. Farley; +Cc: netfilter-devel@vger.kernel.org
Remy D. Farley <one-d-wide@protonmail.com> wrote:
> While messing around with manually encoding nftables expressions, I noticed
> that iptables binary v1.8.11 segfaults with -L and -D <chain> options, if
> there's a rule containing a bitwise operation of a type other than
> mask-and-xor. As I understand, iptables and nft tools only generate rules with
> mask-xor, though the kernel seems to happily accept other types as well.
No, nftables supports this, but iptables does not.
iptables should not segfault, however. Care to make a patch?
Thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: iptables: zero dereference parsing bitwise operations
2025-10-11 13:58 ` Florian Westphal
@ 2025-10-11 20:15 ` Remy D. Farley
2025-10-12 16:46 ` Florian Westphal
2025-10-13 9:04 ` Fernando Fernandez Mancera
0 siblings, 2 replies; 8+ messages in thread
From: Remy D. Farley @ 2025-10-11 20:15 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter-devel@vger.kernel.org
On Saturday, October 11th, 2025 at 13:58, Florian Westphal <fw@strlen.de> wrote:
> Remy D. Farley one-d-wide@protonmail.com wrote:
>
> > While messing around with manually encoding nftables expressions, I noticed
> > that iptables binary v1.8.11 segfaults with -L and -D <chain> options, if
> > there's a rule containing a bitwise operation of a type other than
> > mask-and-xor. As I understand, iptables and nft tools only generate rules with
> > mask-xor, though the kernel seems to happily accept other types as well.
>
>
> No, nftables supports this, but iptables does not.
Hmm, when I run `nft list ruleset` it terminates successfully, but it does
report some errors at the end if the rule from the example is present.
> netlink: Error: Invalid source register 0
> netlink: Error: Bitwise expression has no right-hand expression
> netlink: Error: Relational expression has no left hand side
But I'm not completely sure whether it's not me incorrectly encoding the rule.
For some context, that's how it renders the rule:
> chain example-chain {
> accept
> }
> iptables should not segfault, however. Care to make a patch?
Sure. I think it's fine for now to just check for the operation type and
error with something like "unsupported bitwise operation", like seems to be the
case with nft tool, since this issue appears to be extremely uncommon, if it
hasn't been spotted before.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: iptables: zero dereference parsing bitwise operations
2025-10-11 20:15 ` Remy D. Farley
@ 2025-10-12 16:46 ` Florian Westphal
2025-10-13 9:04 ` Fernando Fernandez Mancera
1 sibling, 0 replies; 8+ messages in thread
From: Florian Westphal @ 2025-10-12 16:46 UTC (permalink / raw)
To: Remy D. Farley; +Cc: netfilter-devel@vger.kernel.org
Remy D. Farley <one-d-wide@protonmail.com> wrote:
> > > While messing around with manually encoding nftables expressions, I noticed
> > > that iptables binary v1.8.11 segfaults with -L and -D <chain> options, if
> > > there's a rule containing a bitwise operation of a type other than
> > > mask-and-xor. As I understand, iptables and nft tools only generate rules with
> > > mask-xor, though the kernel seems to happily accept other types as well.
> >
> >
> > No, nftables supports this, but iptables does not.
>
>
> Hmm, when I run `nft list ruleset` it terminates successfully, but it does
> report some errors at the end if the rule from the example is present.
That just means nft dissector can't make sense of whatever your program
is doing.
> > netlink: Error: Invalid source register 0
Hmm, I am not sure why kernel accepted this in first place,
or maybe a different bug in libnftnl.
> Sure. I think it's fine for now to just check for the operation type and
> error with something like "unsupported bitwise operation", like seems to be the
> case with nft tool, since this issue appears to be extremely uncommon, if it
> hasn't been spotted before.
Yes.
You can also extend nft_is_expr_compatible() so it will exit right away.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: iptables: zero dereference parsing bitwise operations
2025-10-11 20:15 ` Remy D. Farley
2025-10-12 16:46 ` Florian Westphal
@ 2025-10-13 9:04 ` Fernando Fernandez Mancera
2025-10-13 11:43 ` Remy D. Farley
1 sibling, 1 reply; 8+ messages in thread
From: Fernando Fernandez Mancera @ 2025-10-13 9:04 UTC (permalink / raw)
To: Remy D. Farley, Florian Westphal; +Cc: netfilter-devel@vger.kernel.org
On 10/11/25 10:15 PM, Remy D. Farley wrote:
> On Saturday, October 11th, 2025 at 13:58, Florian Westphal <fw@strlen.de> wrote:
>
>> Remy D. Farley one-d-wide@protonmail.com wrote:
>>
>>> While messing around with manually encoding nftables expressions, I noticed
>>> that iptables binary v1.8.11 segfaults with -L and -D <chain> options, if
>>> there's a rule containing a bitwise operation of a type other than
>>> mask-and-xor. As I understand, iptables and nft tools only generate rules with
>>> mask-xor, though the kernel seems to happily accept other types as well.
>>
>>
>> No, nftables supports this, but iptables does not.
>
>
> Hmm, when I run `nft list ruleset` it terminates successfully, but it does
> report some errors at the end if the rule from the example is present.
>
>> netlink: Error: Invalid source register 0
>> netlink: Error: Bitwise expression has no right-hand expression
>> netlink: Error: Relational expression has no left hand side
>
> But I'm not completely sure whether it's not me incorrectly encoding the rule.
>
Hi Remy, could you share the full output of:
'nft --debug=netlink list ruleset'
This will allow me to understand what is the generated bytecode and an
easy way to reproduce this with libnftnl. I am happy to investigate/fix
this on the nft/libnftnl/kernel side :)
> For some context, that's how it renders the rule:
>
>> chain example-chain {
>> accept
>> }
>
>
>> iptables should not segfault, however. Care to make a patch?
>
>
> Sure. I think it's fine for now to just check for the operation type and
> error with something like "unsupported bitwise operation", like seems to be the
> case with nft tool, since this issue appears to be extremely uncommon, if it
> hasn't been spotted before.
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: iptables: zero dereference parsing bitwise operations
2025-10-13 9:04 ` Fernando Fernandez Mancera
@ 2025-10-13 11:43 ` Remy D. Farley
2025-10-14 15:14 ` Fernando Fernandez Mancera
0 siblings, 1 reply; 8+ messages in thread
From: Remy D. Farley @ 2025-10-13 11:43 UTC (permalink / raw)
To: Fernando Fernandez Mancera
Cc: Florian Westphal, netfilter-devel@vger.kernel.org
On Monday, October 13th, 2025 at 09:04, Fernando Fernandez Mancera <fmancera@suse.de> wrote:
> Hi Remy, could you share the full output of:
>
> 'nft --debug=netlink list ruleset'
>
> This will allow me to understand what is the generated bytecode and an
> easy way to reproduce this with libnftnl. I am happy to investigate/fix
> this on the nft/libnftnl/kernel side :)
Hi Fernando,
Not sure if it worth investigating, but here you go.
> $ nft --debug=netlink list ruleset
> table ip filter {
> }
> table ip6 filter {
> }
> table ip mangle {
> }
> table ip6 mangle {
> }
> $ fish example.fish
> [null, null, null]
> $ nft --debug=netlink list ruleset
> ip filter example-chain 565
> [ payload load 4b @ network header + 12 => reg 1 ]
> [ bitwise reg 1 = ( reg 1 | 0x00ffffff ) ]
> [ cmp eq reg 1 0x00030201 ]
> [ immediate reg 0 accept ]
> table ip filter {
> chain example-chain {
> accept
> }
> }
> table ip6 filter {
> }
> table ip mangle {
> }
> table ip6 mangle {
> }
> netlink: Error: Invalid source register 0
> reg 1 = ( reg 1 | 0x00ffffff )
> netlink: Error: Bitwise expression has no right-hand expression
> reg 1 = ( reg 1 | 0x00ffffff )
> netlink: Error: Relational expression has no left hand side
> eq reg 1 0x00030201
> $ iptables -L
> Chain INPUT (policy ACCEPT)
> target prot opt source destination
>
> Chain FORWARD (policy ACCEPT)
> target prot opt source destination
>
> Chain OUTPUT (policy ACCEPT)
> target prot opt source destination
>
> Chain example-chain (0 references)
> target prot opt source destination
> Error: bitwise xor too large
> iptables v1.8.11 (nf_tables): Parsing nftables rule failed
> Perhaps iptables or your kernel needs to be upgraded.
Note that variable `len` in nft_parse_bitwise() is uninitialized prior to
checking the length, so this time iptables happen to error with "bitwise xor
too large" instead of crashing :D
> $ cat example.fish
> iptables -N example-chain
>
> ./tools/net/ynl/pyynl/cli.py \
> --spec Documentation/netlink/specs/nftables.yaml \
> --do getgen --json "{}" \
> --output-json \
> | jq ".id" \
> | read genid
>
> ./tools/net/ynl/pyynl/cli.py \
> --spec Documentation/netlink/specs/nftables.yaml \
> --multi batch-begin '{"genid": '"$genid"', "res-id": 10}' \
> --creat --append --multi newrule '
> {
> "nfgen-family": 2,
> "table": "filter",
> "chain": "example-chain",
> "expressions": {
> "elem": [
> {
> "name": "payload",
> "data": {
> "dreg": 1,
> "base": 1,
> "offset": 12,
> "len": 4
> }
> },
> {
> "name": "bitwise",
> "data": {
> "sreg": 1,
> "dreg": 1,
> "len": 4,
> "op": 4,
> "data": {
> "value": [
> 255,
> 255,
> 255,
> 0
> ]
> }
> }
> },
> {
> "name": "cmp",
> "data": {
> "sreg": 1,
> "op": 0,
> "data": {
> "value": [
> 1,
> 2,
> 3,
> 0
> ]
> }
> }
> },
> {
> "name": "immediate",
> "data": {
> "dreg": 0,
> "data": {
> "verdict": {
> "code": 1
> }
> }
> }
> }
> ]
> }
> }
> ' \
> --multi batch-end '{}' \
> --output-json
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: iptables: zero dereference parsing bitwise operations
2025-10-13 11:43 ` Remy D. Farley
@ 2025-10-14 15:14 ` Fernando Fernandez Mancera
2025-10-14 15:29 ` Florian Westphal
0 siblings, 1 reply; 8+ messages in thread
From: Fernando Fernandez Mancera @ 2025-10-14 15:14 UTC (permalink / raw)
To: Remy D. Farley; +Cc: Florian Westphal, netfilter-devel@vger.kernel.org
On 10/13/25 1:43 PM, Remy D. Farley wrote:
> On Monday, October 13th, 2025 at 09:04, Fernando Fernandez Mancera <fmancera@suse.de> wrote:
>
>> Hi Remy, could you share the full output of:
>>
>> 'nft --debug=netlink list ruleset'
>>
>> This will allow me to understand what is the generated bytecode and an
>> easy way to reproduce this with libnftnl. I am happy to investigate/fix
>> this on the nft/libnftnl/kernel side :)
>
>
> Hi Fernando,
>
> Not sure if it worth investigating, but here you go.
>
>
I have reproduced this and confirmed that the right source register is
being set (NFT_REG_1) and that libnftnl is reporting it correctly. The
problem is on nft command line tool side.. I do not think it is worth
going deeper as it is probably related to nftables not being able to
delinearize this rule as it is not supported by nft itself.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: iptables: zero dereference parsing bitwise operations
2025-10-14 15:14 ` Fernando Fernandez Mancera
@ 2025-10-14 15:29 ` Florian Westphal
0 siblings, 0 replies; 8+ messages in thread
From: Florian Westphal @ 2025-10-14 15:29 UTC (permalink / raw)
To: Fernando Fernandez Mancera
Cc: Remy D. Farley, netfilter-devel@vger.kernel.org
Fernando Fernandez Mancera <fmancera@suse.de> wrote:
> >
> >> Hi Remy, could you share the full output of:
> >>
> >> 'nft --debug=netlink list ruleset'
> >>
> >> This will allow me to understand what is the generated bytecode and an
> >> easy way to reproduce this with libnftnl. I am happy to investigate/fix
> >> this on the nft/libnftnl/kernel side :)
> >
> >
> > Hi Fernando,
> >
> > Not sure if it worth investigating, but here you go.
> >
> >
>
> I have reproduced this and confirmed that the right source register is
> being set (NFT_REG_1) and that libnftnl is reporting it correctly. The
> problem is on nft command line tool side.. I do not think it is worth
> going deeper as it is probably related to nftables not being able to
> delinearize this rule as it is not supported by nft itself.
What the rule is doing is supported, but nft will transform it to use
xor/and, as that will work on all nf_tables versions rather than only
kernels that support NFT_BITWISE_OR.
I think it would be possible to extend netlink_delinerize.c to support
it but its technically not needed.
nft can also not be expected to ever be able to make sense of a ruleset
generated by something else, there is just too much variance to always
be able to map this back to nft grammar.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-10-14 15:29 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-10 21:16 iptables: zero dereference parsing bitwise operations Remy D. Farley
2025-10-11 13:58 ` Florian Westphal
2025-10-11 20:15 ` Remy D. Farley
2025-10-12 16:46 ` Florian Westphal
2025-10-13 9:04 ` Fernando Fernandez Mancera
2025-10-13 11:43 ` Remy D. Farley
2025-10-14 15:14 ` Fernando Fernandez Mancera
2025-10-14 15:29 ` Florian Westphal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).