]> git.ipfire.org Git - thirdparty/nftables.git/commit
payload: don't adjust offsets of autogenerated dependency expressions
authorFlorian Westphal <fw@strlen.de>
Tue, 28 Sep 2021 12:16:48 +0000 (14:16 +0200)
committerFlorian Westphal <fw@strlen.de>
Wed, 29 Sep 2021 16:31:19 +0000 (18:31 +0200)
commit8a9762dbf15433b6dc361ec03cb3d6f0db652a85
tree06a4b7a33437badf8f796115fad41ffa68cb96b9
parent0693edb9eb01fa5a479dcca7d30b06f52806d22a
payload: don't adjust offsets of autogenerated dependency expressions

Pablo says:
  user reports that this is broken:
  nft --debug=netlink add rule bridge filter forward vlan id 100 vlan id set 200
[..]
    [ payload load 2b @ link header + 14 => reg 1 ]
[..]
    [ payload load 2b @ link header + 28 => reg 1 ]
    [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x0000c800 ]
    [ payload write reg 1 => 2b @ link header + 14 csum_type 0 csum_off 0 csum_flags 0x0 ]

    offset says 28, it is assuming q-in-q, in this case it is mangling the
    existing header.

The problem here is that 'vlan id set 200' needs a read-modify-write
cycle because 'vlan id set' has to preserve bits located in the same byte area
as the vlan id.

The first 'payload load' at offset 14 is generated via 'vlan id 100',
this part is ok.

The second 'payload load' at offset 28 is the bogus one.
Its added as a dependency, but then adjusted because nft evaluation
considers this identical to 'vlan id 1 vlan id '2, where nft assumes
q-in-q.

To fix this, skip offset adjustments for raw expressions and mark the
dependency-generated payload instruction as such.

This is fine because raw payload operations assume that user specifies
base/offset/length manually.

Also add a test case for this.

Reported-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
src/evaluate.c
src/payload.c
tests/py/bridge/vlan.t
tests/py/bridge/vlan.t.json
tests/py/bridge/vlan.t.payload
tests/py/bridge/vlan.t.payload.netdev