Skip to content

Commit

Permalink
netfilter: nf_tables: fix 'exist' matching on bigendian arches
Browse files Browse the repository at this point in the history
Maze reports "tcp option fastopen exists" fails to match on
OpenWrt 22.03.5, r20134-5f15225c1e (5.10.176) router.

"tcp option fastopen exists" translates to:
inet
  [ exthdr load tcpopt 1b @ 34 + 0 present => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]

.. but existing nft userspace generates a 1-byte compare.

On LSB (x86), "*reg32 = 1" is identical to nft_reg_store8(reg32, 1), but
not on MSB, which will place the 1 last. IOW, on bigendian aches the cmp8
is awalys false.

Make sure we store this in a consistent fashion, so existing userspace
will also work on MSB (bigendian).

Regardless of this patch we can also change nft userspace to generate
'reg32 == 0' and 'reg32 != 0' instead of u8 == 0 // u8 == 1 when
adding 'option x missing/exists' expressions as well.

Fixes: 3c1fece ("netfilter: nft_exthdr: Allow checking TCP option presence, too")
Fixes: b9f9a48 ("netfilter: nft_exthdr: add boolean DCCP option matching")
Fixes: 055c4b3 ("netfilter: nft_fib: Support existence check")
Reported-by: Maciej Żenczykowski <zenczykowski@gmail.com>
Closes: https://lore.kernel.org/netfilter-devel/CAHo-OozyEqHUjL2-ntATzeZOiuftLWZ_HU6TOM_js4qLfDEAJg@mail.gmail.com/
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Florian Westphal authored and ummakynes committed Dec 6, 2023
1 parent 317eb96 commit 63331e3
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 4 deletions.
4 changes: 2 additions & 2 deletions net/netfilter/nft_exthdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr,

offset = i + priv->offset;
if (priv->flags & NFT_EXTHDR_F_PRESENT) {
*dest = 1;
nft_reg_store8(dest, 1);
} else {
if (priv->len % NFT_REG32_SIZE)
dest[priv->len / NFT_REG32_SIZE] = 0;
Expand Down Expand Up @@ -461,7 +461,7 @@ static void nft_exthdr_dccp_eval(const struct nft_expr *expr,
type = bufp[0];

if (type == priv->type) {
*dest = 1;
nft_reg_store8(dest, 1);
return;
}

Expand Down
8 changes: 6 additions & 2 deletions net/netfilter/nft_fib.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,15 @@ void nft_fib_store_result(void *reg, const struct nft_fib *priv,
switch (priv->result) {
case NFT_FIB_RESULT_OIF:
index = dev ? dev->ifindex : 0;
*dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index;
if (priv->flags & NFTA_FIB_F_PRESENT)
nft_reg_store8(dreg, !!index);
else
*dreg = index;

break;
case NFT_FIB_RESULT_OIFNAME:
if (priv->flags & NFTA_FIB_F_PRESENT)
*dreg = !!dev;
nft_reg_store8(dreg, !!dev);
else
strscpy_pad(reg, dev ? dev->name : "", IFNAMSIZ);
break;
Expand Down

0 comments on commit 63331e3

Please sign in to comment.