[PATCH 4.14 28/61] netfilter: nft_meta: fix wrong value dereference in nft_meta_set_eval

From: Greg Kroah-Hartman
Date: Fri Jul 06 2018 - 01:51:06 EST


4.14-stable review patch. If anyone has any objections, please let me know.

------------------

From: Taehee Yoo <ap420073@xxxxxxxxx>

commit 97a0549b15a0b466c47f6a0143a490a082c64b4e upstream.

In the nft_meta_set_eval, nftrace value is dereferenced as u32 from sreg.
But correct type is u8. so that sometimes incorrect value is dereferenced.

Steps to reproduce:

%nft add table ip filter
%nft add chain ip filter input { type filter hook input priority 4\; }
%nft add rule ip filter input nftrace set 0
%nft monitor

Sometimes, we can see trace messages.

trace id 16767227 ip filter input packet: iif "enp2s0"
ether saddr xx:xx:xx:xx:xx:xx ether daddr xx:xx:xx:xx:xx:xx
ip saddr 192.168.0.1 ip daddr 255.255.255.255 ip dscp cs0
ip ecn not-ect ip
trace id 16767227 ip filter input rule nftrace set 0 (verdict continue)
trace id 16767227 ip filter input verdict continue
trace id 16767227 ip filter input

Signed-off-by: Taehee Yoo <ap420073@xxxxxxxxx>
Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
net/netfilter/nft_meta.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -229,7 +229,7 @@ void nft_meta_set_eval(const struct nft_
struct sk_buff *skb = pkt->skb;
u32 *sreg = &regs->data[meta->sreg];
u32 value = *sreg;
- u8 pkt_type;
+ u8 value8;

switch (meta->key) {
case NFT_META_MARK:
@@ -239,15 +239,17 @@ void nft_meta_set_eval(const struct nft_
skb->priority = value;
break;
case NFT_META_PKTTYPE:
- pkt_type = nft_reg_load8(sreg);
+ value8 = nft_reg_load8(sreg);

- if (skb->pkt_type != pkt_type &&
- skb_pkt_type_ok(pkt_type) &&
+ if (skb->pkt_type != value8 &&
+ skb_pkt_type_ok(value8) &&
skb_pkt_type_ok(skb->pkt_type))
- skb->pkt_type = pkt_type;
+ skb->pkt_type = value8;
break;
case NFT_META_NFTRACE:
- skb->nf_trace = !!value;
+ value8 = nft_reg_load8(sreg);
+
+ skb->nf_trace = !!value8;
break;
default:
WARN_ON(1);