netfilter: x_tables: initialise match/target check parameter struct
authorFlorian Westphal <fw@strlen.de>
Thu, 7 Jun 2018 19:34:43 +0000 (21:34 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Jul 2018 09:39:32 +0000 (11:39 +0200)
commit c568503ef02030f169c9e19204def610a3510918 upstream.

syzbot reports following splat:

BUG: KMSAN: uninit-value in ebt_stp_mt_check+0x24b/0x450
 net/bridge/netfilter/ebt_stp.c:162
 ebt_stp_mt_check+0x24b/0x450 net/bridge/netfilter/ebt_stp.c:162
 xt_check_match+0x1438/0x1650 net/netfilter/x_tables.c:506
 ebt_check_match net/bridge/netfilter/ebtables.c:372 [inline]
 ebt_check_entry net/bridge/netfilter/ebtables.c:702 [inline]

The uninitialised access is
   xt_mtchk_param->nft_compat

... which should be set to 0.
Fix it by zeroing the struct beforehand, same for tgchk.

ip(6)tables targetinfo uses c99-style initialiser, so no change
needed there.

Reported-by: syzbot+da4494182233c23a5fcf@syzkaller.appspotmail.com
Fixes: 55917a21d0cc0 ("netfilter: x_tables: add context to know if extension runs from nft_compat")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/bridge/netfilter/ebtables.c
net/ipv4/netfilter/ip_tables.c
net/ipv6/netfilter/ip6_tables.c

index e27fb6e97d1879dc996a1732aef4efa55a415208..25738b20676d50d98f573f0c609738d4ee62c103 100644 (file)
@@ -696,6 +696,8 @@ ebt_check_entry(struct ebt_entry *e, struct net *net,
        }
        i = 0;
 
+       memset(&mtpar, 0, sizeof(mtpar));
+       memset(&tgpar, 0, sizeof(tgpar));
        mtpar.net       = tgpar.net       = net;
        mtpar.table     = tgpar.table     = name;
        mtpar.entryinfo = tgpar.entryinfo = e;
index 1a925f2394ad3394b4b7b4408f0b9a7066a00960..114d4bef1bec291ca56173c5370cd20dbf2996ae 100644 (file)
@@ -541,6 +541,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
                return -ENOMEM;
 
        j = 0;
+       memset(&mtpar, 0, sizeof(mtpar));
        mtpar.net       = net;
        mtpar.table     = name;
        mtpar.entryinfo = &e->ip;
index c5fe42e6b7f7a78ab7767ffbe101adb360c315ee..2e51e01569030a3cc7d0837470372728b765c412 100644 (file)
@@ -561,6 +561,7 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
                return -ENOMEM;
 
        j = 0;
+       memset(&mtpar, 0, sizeof(mtpar));
        mtpar.net       = net;
        mtpar.table     = name;
        mtpar.entryinfo = &e->ipv6;