[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200803182001.9243-1-ssuryaextr@gmail.com>
Date: Mon, 3 Aug 2020 14:20:01 -0400
From: Stephen Suryaputra <ssuryaextr@...il.com>
To: netfilter-devel@...r.kernel.org
Cc: netdev@...r.kernel.org, Stephen Suryaputra <ssuryaextr@...il.com>
Subject: [PATCH nf] netfilter: nf_tables: nft_exthdr: the presence return value should be little-endian
On big-endian machine, the returned register data when the exthdr is
present is not being compared correctly because little-endian is
assumed. The function nft_cmp_fast_mask(), called by nft_cmp_fast_eval()
and nft_cmp_fast_init(), calls cpu_to_le32().
The following dump also shows that little endian is assumed:
$ nft --debug=netlink add rule ip recordroute forward ip option rr exists counter
ip
[ exthdr load ipv4 1b @ 7 + 0 present => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
[ counter pkts 0 bytes 0 ]
Lastly, debug print in nft_cmp_fast_init() and nft_cmp_fast_eval() when
RR option exists in the packet shows that the comparison fails because
the assumption:
nft_cmp_fast_init:189 priv->sreg=4 desc.len=8 mask=0xff000000 data.data[0]=0x10003e0
nft_cmp_fast_eval:57 regs->data[priv->sreg=4]=0x1 mask=0xff000000 priv->data=0x1000000
Fixes: dbb5281a1f84 ("netfilter: nf_tables: add support for matching IPv4 options")
Fixes: c078ca3b0c5b ("netfilter: nft_exthdr: Add support for existence check")
Signed-off-by: Stephen Suryaputra <ssuryaextr@...il.com>
---
net/netfilter/nft_exthdr.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index 07782836fad6..50e4935585e3 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -44,7 +44,7 @@ static void nft_exthdr_ipv6_eval(const struct nft_expr *expr,
err = ipv6_find_hdr(pkt->skb, &offset, priv->type, NULL, NULL);
if (priv->flags & NFT_EXTHDR_F_PRESENT) {
- *dest = (err >= 0);
+ *dest = cpu_to_le32(err >= 0);
return;
} else if (err < 0) {
goto err;
@@ -141,7 +141,7 @@ static void nft_exthdr_ipv4_eval(const struct nft_expr *expr,
err = ipv4_find_option(nft_net(pkt), skb, &offset, priv->type);
if (priv->flags & NFT_EXTHDR_F_PRESENT) {
- *dest = (err >= 0);
+ *dest = cpu_to_le32(err >= 0);
return;
} else if (err < 0) {
goto err;
--
2.25.1
Powered by blists - more mailing lists