netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* general protection fault in hash_ipportnet4_uadt
@ 2020-01-07 16:03 syzbot
  2020-01-07 17:28 ` syzbot
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: syzbot @ 2020-01-07 16:03 UTC (permalink / raw)
  To: allison, coreteam, davem, fw, info, jeremy, kadlec, kstewart,
	linux-kernel, netdev, netfilter-devel, pablo, syzkaller-bugs,
	tglx

Hello,

syzbot found the following crash on:

HEAD commit:    1b935183 Merge branch 'Unique-mv88e6xxx-IRQ-names'
git tree:       net-next
console output: https://syzkaller.appspot.com/x/log.txt?x=15352325e00000
kernel config:  https://syzkaller.appspot.com/x/.config?x=977dda960db4d1e7
dashboard link: https://syzkaller.appspot.com/bug?extid=34bd2369d38707f3f4a7
compiler:       gcc (GCC) 9.0.0 20181231 (experimental)

Unfortunately, I don't have any reproducer for this crash yet.

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+34bd2369d38707f3f4a7@syzkaller.appspotmail.com

kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN
CPU: 1 PID: 9396 Comm: syz-executor.3 Not tainted 5.5.0-rc4-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
RIP: 0010:hash_ipportnet4_uadt+0x20b/0x13e0  
net/netfilter/ipset/ip_set_hash_ipportnet.c:173
Code: 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 71 0c 00 00 4c 89  
e2 45 8b 6d 04 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <0f> b6 14 02 4c  
89 e0 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 2c
RSP: 0018:ffffc9000793f150 EFLAGS: 00010246
RAX: dffffc0000000000 RBX: ffffc9000793f320 RCX: ffffc9000f81d000
RDX: 0000000000000000 RSI: ffffffff86821788 RDI: ffff88809f886430
RBP: ffffc9000793f2b8 R08: 0000000000000000 R09: 0000000000000000
R10: ffffed1015d2703c R11: ffff8880ae9381e3 R12: 0000000000000000
R13: 00000000ff7f0000 R14: ffffc9000793f220 R15: ffff8880a355ea00
FS:  00007fa58b436700(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000340 CR3: 000000009d628000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
  ip_set_utest+0x55b/0x890 net/netfilter/ipset/ip_set_core.c:1867
  nfnetlink_rcv_msg+0xcf2/0xfb0 net/netfilter/nfnetlink.c:229
  netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477
  nfnetlink_rcv+0x1ba/0x460 net/netfilter/nfnetlink.c:563
  netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline]
  netlink_unicast+0x58c/0x7d0 net/netlink/af_netlink.c:1328
  netlink_sendmsg+0x91c/0xea0 net/netlink/af_netlink.c:1917
  sock_sendmsg_nosec net/socket.c:643 [inline]
  sock_sendmsg+0xd7/0x130 net/socket.c:663
  ____sys_sendmsg+0x753/0x880 net/socket.c:2342
  ___sys_sendmsg+0x100/0x170 net/socket.c:2396
  __sys_sendmsg+0x105/0x1d0 net/socket.c:2429
  __do_sys_sendmsg net/socket.c:2438 [inline]
  __se_sys_sendmsg net/socket.c:2436 [inline]
  __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2436
  do_syscall_64+0xfa/0x790 arch/x86/entry/common.c:294
  entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x45af49
Code: ad b6 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7  
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff  
ff 0f 83 7b b6 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007fa58b435c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 000000000045af49
RDX: 0000000000000000 RSI: 0000000020000340 RDI: 0000000000000003
RBP: 000000000075bf20 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007fa58b4366d4
R13: 00000000004c9e62 R14: 00000000004e2e98 R15: 00000000ffffffff
Modules linked in:
---[ end trace 7a7fd1554086524f ]---
RIP: 0010:hash_ipportnet4_uadt+0x20b/0x13e0  
net/netfilter/ipset/ip_set_hash_ipportnet.c:173
Code: 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 71 0c 00 00 4c 89  
e2 45 8b 6d 04 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <0f> b6 14 02 4c  
89 e0 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 2c
RSP: 0018:ffffc9000793f150 EFLAGS: 00010246
RAX: dffffc0000000000 RBX: ffffc9000793f320 RCX: ffffc9000f81d000
RDX: 0000000000000000 RSI: ffffffff86821788 RDI: ffff88809f886430
RBP: ffffc9000793f2b8 R08: 0000000000000000 R09: 0000000000000000
R10: ffffed1015d2703c R11: ffff8880ae9381e3 R12: 0000000000000000
R13: 00000000ff7f0000 R14: ffffc9000793f220 R15: ffff8880a355ea00
FS:  00007fa58b436700(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000340 CR3: 000000009d628000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400


---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: general protection fault in hash_ipportnet4_uadt
  2020-01-07 16:03 general protection fault in hash_ipportnet4_uadt syzbot
@ 2020-01-07 17:28 ` syzbot
  2020-01-08  9:59 ` [PATCH nf] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present Florian Westphal
  2020-01-08 16:53 ` general protection fault in hash_ipportnet4_uadt syzbot
  2 siblings, 0 replies; 8+ messages in thread
From: syzbot @ 2020-01-07 17:28 UTC (permalink / raw)
  To: allison, coreteam, davem, fw, info, jeremy, kadlec, kstewart,
	linux-kernel, netdev, netfilter-devel, pablo, syzkaller-bugs,
	tglx

syzbot has found a reproducer for the following crash on:

HEAD commit:    c101fffc Merge tag 'mlx5-fixes-2020-01-06' of git://git.ke..
git tree:       net
console output: https://syzkaller.appspot.com/x/log.txt?x=13f4f3c1e00000
kernel config:  https://syzkaller.appspot.com/x/.config?x=f2f3ef188b7e16cf
dashboard link: https://syzkaller.appspot.com/bug?extid=34bd2369d38707f3f4a7
compiler:       gcc (GCC) 9.0.0 20181231 (experimental)
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=14b35ec6e00000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=13044076e00000

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+34bd2369d38707f3f4a7@syzkaller.appspotmail.com

kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN
CPU: 1 PID: 9656 Comm: syz-executor756 Not tainted 5.5.0-rc4-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
RIP: 0010:hash_ipportnet4_uadt+0x20b/0x13e0  
net/netfilter/ipset/ip_set_hash_ipportnet.c:173
Code: 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 71 0c 00 00 4c 89  
e2 45 8b 6d 04 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <0f> b6 14 02 4c  
89 e0 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 2c
RSP: 0018:ffffc90001ee7150 EFLAGS: 00010246
RAX: dffffc0000000000 RBX: ffffc90001ee7320 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffffffff867e4e78 RDI: ffff8880a7f08070
RBP: ffffc90001ee72b8 R08: 0000000000000000 R09: 0000000000000000
R10: ffffed1015d2703c R11: ffff8880ae9381e3 R12: 0000000000000000
R13: 0000000002000000 R14: ffffc90001ee7220 R15: ffff8880a4c3a400
FS:  0000000000e4b880(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000446 CR3: 000000009e154000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
  ip_set_utest+0x55b/0x890 net/netfilter/ipset/ip_set_core.c:1867
  nfnetlink_rcv_msg+0xcf2/0xfb0 net/netfilter/nfnetlink.c:229
  netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477
  nfnetlink_rcv+0x1ba/0x460 net/netfilter/nfnetlink.c:563
  netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline]
  netlink_unicast+0x58c/0x7d0 net/netlink/af_netlink.c:1328
  netlink_sendmsg+0x91c/0xea0 net/netlink/af_netlink.c:1917
  sock_sendmsg_nosec net/socket.c:639 [inline]
  sock_sendmsg+0xd7/0x130 net/socket.c:659
  ____sys_sendmsg+0x753/0x880 net/socket.c:2330
  ___sys_sendmsg+0x100/0x170 net/socket.c:2384
  __sys_sendmsg+0x105/0x1d0 net/socket.c:2417
  __do_sys_sendmsg net/socket.c:2426 [inline]
  __se_sys_sendmsg net/socket.c:2424 [inline]
  __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2424
  do_syscall_64+0xfa/0x790 arch/x86/entry/common.c:294
  entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x440839
Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7  
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff  
ff 0f 83 fb 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007ffde8ed0ad8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000440839
RDX: 0000000000000002 RSI: 0000000020000140 RDI: 0000000000000004
RBP: 00000000006ca018 R08: 0000000000000008 R09: 00000000004002c8
R10: 000000000000204e R11: 0000000000000246 R12: 00000000004020c0
R13: 0000000000402150 R14: 0000000000000000 R15: 0000000000000000
Modules linked in:
---[ end trace 4497e0a4dc04971d ]---
RIP: 0010:hash_ipportnet4_uadt+0x20b/0x13e0  
net/netfilter/ipset/ip_set_hash_ipportnet.c:173
Code: 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 71 0c 00 00 4c 89  
e2 45 8b 6d 04 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <0f> b6 14 02 4c  
89 e0 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 2c
RSP: 0018:ffffc90001ee7150 EFLAGS: 00010246
RAX: dffffc0000000000 RBX: ffffc90001ee7320 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffffffff867e4e78 RDI: ffff8880a7f08070
RBP: ffffc90001ee72b8 R08: 0000000000000000 R09: 0000000000000000
R10: ffffed1015d2703c R11: ffff8880ae9381e3 R12: 0000000000000000
R13: 0000000002000000 R14: ffffc90001ee7220 R15: ffff8880a4c3a400
FS:  0000000000e4b880(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000446 CR3: 000000009e154000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH nf] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present
  2020-01-07 16:03 general protection fault in hash_ipportnet4_uadt syzbot
  2020-01-07 17:28 ` syzbot
@ 2020-01-08  9:59 ` Florian Westphal
  2020-01-08 10:05   ` Kadlecsik József
                     ` (2 more replies)
  2020-01-08 16:53 ` general protection fault in hash_ipportnet4_uadt syzbot
  2 siblings, 3 replies; 8+ messages in thread
From: Florian Westphal @ 2020-01-08  9:59 UTC (permalink / raw)
  To: netfilter-devel
  Cc: netdev, syzkaller-bugs, Florian Westphal, Jozsef Kadlecsik,
	syzbot+34bd2369d38707f3f4a7

The set uadt functions assume lineno is never NULL, but it is in
case of ip_set_utest().

syzkaller managed to generate a netlink message that calls this with
LINENO attr present:

general protection fault: 0000 [#1] PREEMPT SMP KASAN
RIP: 0010:hash_mac4_uadt+0x1bc/0x470 net/netfilter/ipset/ip_set_hash_mac.c:104
Call Trace:
 ip_set_utest+0x55b/0x890 net/netfilter/ipset/ip_set_core.c:1867
 nfnetlink_rcv_msg+0xcf2/0xfb0 net/netfilter/nfnetlink.c:229
 netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477
 nfnetlink_rcv+0x1ba/0x460 net/netfilter/nfnetlink.c:563

pass a dummy lineno storage, its easier than patching all set
implementations.

This seems to be a day-0 bug.

Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Reported-by: syzbot+34bd2369d38707f3f4a7@syzkaller.appspotmail.com
Fixes: a7b4f989a6294 ("netfilter: ipset: IP set core support")
Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/netfilter/ipset/ip_set_core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 169e0a04f814..cf895bc80871 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1848,6 +1848,7 @@ static int ip_set_utest(struct net *net, struct sock *ctnl, struct sk_buff *skb,
 	struct ip_set *set;
 	struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {};
 	int ret = 0;
+	u32 lineno;
 
 	if (unlikely(protocol_min_failed(attr) ||
 		     !attr[IPSET_ATTR_SETNAME] ||
@@ -1864,7 +1865,7 @@ static int ip_set_utest(struct net *net, struct sock *ctnl, struct sk_buff *skb,
 		return -IPSET_ERR_PROTOCOL;
 
 	rcu_read_lock_bh();
-	ret = set->variant->uadt(set, tb, IPSET_TEST, NULL, 0, 0);
+	ret = set->variant->uadt(set, tb, IPSET_TEST, &lineno, 0, 0);
 	rcu_read_unlock_bh();
 	/* Userspace can't trigger element to be re-added */
 	if (ret == -EAGAIN)
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH nf] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present
  2020-01-08  9:59 ` [PATCH nf] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present Florian Westphal
@ 2020-01-08 10:05   ` Kadlecsik József
  2020-01-08 10:37   ` [PATCH] " Jan Engelhardt
  2020-01-08 22:32   ` [PATCH nf] " Pablo Neira Ayuso
  2 siblings, 0 replies; 8+ messages in thread
From: Kadlecsik József @ 2020-01-08 10:05 UTC (permalink / raw)
  To: Florian Westphal
  Cc: netfilter-devel, netdev, syzkaller-bugs, syzbot+34bd2369d38707f3f4a7

On Wed, 8 Jan 2020, Florian Westphal wrote:

> The set uadt functions assume lineno is never NULL, but it is in
> case of ip_set_utest().
> 
> syzkaller managed to generate a netlink message that calls this with
> LINENO attr present:
> 
> general protection fault: 0000 [#1] PREEMPT SMP KASAN
> RIP: 0010:hash_mac4_uadt+0x1bc/0x470 net/netfilter/ipset/ip_set_hash_mac.c:104
> Call Trace:
>  ip_set_utest+0x55b/0x890 net/netfilter/ipset/ip_set_core.c:1867
>  nfnetlink_rcv_msg+0xcf2/0xfb0 net/netfilter/nfnetlink.c:229
>  netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477
>  nfnetlink_rcv+0x1ba/0x460 net/netfilter/nfnetlink.c:563
> 
> pass a dummy lineno storage, its easier than patching all set
> implementations.

I have just written the same patch... you were faster.
 
> This seems to be a day-0 bug.

Yes, alas. One could extend the check of attributes in ip_set_utest() to 
bail out with protocol error if attr[IPSET_ATTR_LINENO] is present.
 
> Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>

Acked-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>

Best regards,
Jozsef

> Reported-by: syzbot+34bd2369d38707f3f4a7@syzkaller.appspotmail.com
> Fixes: a7b4f989a6294 ("netfilter: ipset: IP set core support")
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
>  net/netfilter/ipset/ip_set_core.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
> index 169e0a04f814..cf895bc80871 100644
> --- a/net/netfilter/ipset/ip_set_core.c
> +++ b/net/netfilter/ipset/ip_set_core.c
> @@ -1848,6 +1848,7 @@ static int ip_set_utest(struct net *net, struct sock *ctnl, struct sk_buff *skb,
>  	struct ip_set *set;
>  	struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {};
>  	int ret = 0;
> +	u32 lineno;
>  
>  	if (unlikely(protocol_min_failed(attr) ||
>  		     !attr[IPSET_ATTR_SETNAME] ||
> @@ -1864,7 +1865,7 @@ static int ip_set_utest(struct net *net, struct sock *ctnl, struct sk_buff *skb,
>  		return -IPSET_ERR_PROTOCOL;
>  
>  	rcu_read_lock_bh();
> -	ret = set->variant->uadt(set, tb, IPSET_TEST, NULL, 0, 0);
> +	ret = set->variant->uadt(set, tb, IPSET_TEST, &lineno, 0, 0);
>  	rcu_read_unlock_bh();
>  	/* Userspace can't trigger element to be re-added */
>  	if (ret == -EAGAIN)
> -- 
> 2.24.1
> 
> 

-
E-mail  : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics
          H-1525 Budapest 114, POB. 49, Hungary

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present
  2020-01-08  9:59 ` [PATCH nf] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present Florian Westphal
  2020-01-08 10:05   ` Kadlecsik József
@ 2020-01-08 10:37   ` Jan Engelhardt
  2020-01-08 12:43     ` Kadlecsik József
  2020-01-08 22:32   ` [PATCH nf] " Pablo Neira Ayuso
  2 siblings, 1 reply; 8+ messages in thread
From: Jan Engelhardt @ 2020-01-08 10:37 UTC (permalink / raw)
  To: fw
  Cc: netfilter-devel, netdev, syzkaller-bugs, kadlec,
	syzbot+34bd2369d38707f3f4a7

The set uadt functions assume lineno is never NULL, but it is in
case of ip_set_utest().

syzkaller managed to generate a netlink message that calls this with
LINENO attr present:

general protection fault: 0000 [#1] PREEMPT SMP KASAN
RIP: 0010:hash_mac4_uadt+0x1bc/0x470 net/netfilter/ipset/ip_set_hash_mac.c:104
Call Trace:
 ip_set_utest+0x55b/0x890 net/netfilter/ipset/ip_set_core.c:1867
 nfnetlink_rcv_msg+0xcf2/0xfb0 net/netfilter/nfnetlink.c:229
 netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477
 nfnetlink_rcv+0x1ba/0x460 net/netfilter/nfnetlink.c:563

Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Reported-by: syzbot+34bd2369d38707f3f4a7@syzkaller.appspotmail.com
Fixes: a7b4f989a6294 ("netfilter: ipset: IP set core support")
Signed-off-by: Jan Engelhardt <jengelh@inai.de>
---

 "Pass a dummy lineno storage, its easier than patching all set
 implementations". This may be so, but that does not mean patching
 the implementations is much harder (does not even warrant running
 coccinelle), so I present this alternative patch.


 net/netfilter/ipset/ip_set_bitmap_ip.c       | 2 +-
 net/netfilter/ipset/ip_set_bitmap_ipmac.c    | 2 +-
 net/netfilter/ipset/ip_set_bitmap_port.c     | 2 +-
 net/netfilter/ipset/ip_set_hash_ip.c         | 4 ++--
 net/netfilter/ipset/ip_set_hash_ipmac.c      | 4 ++--
 net/netfilter/ipset/ip_set_hash_ipmark.c     | 4 ++--
 net/netfilter/ipset/ip_set_hash_ipport.c     | 4 ++--
 net/netfilter/ipset/ip_set_hash_ipportip.c   | 4 ++--
 net/netfilter/ipset/ip_set_hash_ipportnet.c  | 4 ++--
 net/netfilter/ipset/ip_set_hash_mac.c        | 2 +-
 net/netfilter/ipset/ip_set_hash_net.c        | 4 ++--
 net/netfilter/ipset/ip_set_hash_netiface.c   | 4 ++--
 net/netfilter/ipset/ip_set_hash_netnet.c     | 4 ++--
 net/netfilter/ipset/ip_set_hash_netport.c    | 4 ++--
 net/netfilter/ipset/ip_set_hash_netportnet.c | 4 ++--
 net/netfilter/ipset/ip_set_list_set.c        | 2 +-
 16 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c
index abe8f77d7d23..9403730ca686 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ip.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ip.c
@@ -137,7 +137,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 	int ret = 0;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP]))
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
index b618713297da..b16ebdddca83 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
@@ -248,7 +248,7 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[],
 	u32 ip = 0;
 	int ret = 0;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP]))
diff --git a/net/netfilter/ipset/ip_set_bitmap_port.c b/net/netfilter/ipset/ip_set_bitmap_port.c
index 23d6095cb196..cb22d85cef01 100644
--- a/net/netfilter/ipset/ip_set_bitmap_port.c
+++ b/net/netfilter/ipset/ip_set_bitmap_port.c
@@ -161,7 +161,7 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
 	u16 port_to;
 	int ret = 0;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
index 5d6d68eaf6a9..1195ee3539fb 100644
--- a/net/netfilter/ipset/ip_set_hash_ip.c
+++ b/net/netfilter/ipset/ip_set_hash_ip.c
@@ -104,7 +104,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
 	u32 ip = 0, ip_to = 0, hosts;
 	int ret = 0;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP]))
@@ -238,7 +238,7 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[],
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP]))
diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
index eceb7bc4a93a..9a1dc251988e 100644
--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
+++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
@@ -126,7 +126,7 @@ hash_ipmac4_uadt(struct ip_set *set, struct nlattr *tb[],
 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBQUEUE)))
 		return -IPSET_ERR_PROTOCOL;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &e.ip) ||
@@ -245,7 +245,7 @@ hash_ipmac6_uadt(struct ip_set *set, struct nlattr *tb[],
 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBQUEUE)))
 		return -IPSET_ERR_PROTOCOL;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c
index aba1df617d6e..6b975573db7c 100644
--- a/net/netfilter/ipset/ip_set_hash_ipmark.c
+++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
@@ -103,7 +103,7 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
 	u32 ip, ip_to = 0;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -228,7 +228,7 @@ hash_ipmark6_uadt(struct ip_set *set, struct nlattr *tb[],
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] ||
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
index 1ff228717e29..7cec674af6de 100644
--- a/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -112,7 +112,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
 	bool with_ports = false;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -270,7 +270,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
 	bool with_ports = false;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] ||
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
index fa88afd812fa..9ea4b8119cbe 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -115,7 +115,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
 	bool with_ports = false;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
@@ -281,7 +281,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
 	bool with_ports = false;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
index eef6ecfcb409..bf089de34330 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -169,7 +169,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 	u8 cidr;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
@@ -419,7 +419,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
 	u8 cidr;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
diff --git a/net/netfilter/ipset/ip_set_hash_mac.c b/net/netfilter/ipset/ip_set_hash_mac.c
index 0b61593165ef..6cfabfedc44f 100644
--- a/net/netfilter/ipset/ip_set_hash_mac.c
+++ b/net/netfilter/ipset/ip_set_hash_mac.c
@@ -100,7 +100,7 @@ hash_mac4_uadt(struct ip_set *set, struct nlattr *tb[],
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_ETHER] ||
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
index 136cf0781d3a..3d74b249db7b 100644
--- a/net/netfilter/ipset/ip_set_hash_net.c
+++ b/net/netfilter/ipset/ip_set_hash_net.c
@@ -142,7 +142,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
 	u32 ip = 0, ip_to = 0;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -308,7 +308,7 @@ hash_net6_uadt(struct ip_set *set, struct nlattr *tb[],
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] ||
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index be5e95a0d876..32fc8f794d6a 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -204,7 +204,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
 	u32 ip = 0, ip_to = 0;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -416,7 +416,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] ||
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
index da4ef910b12d..789fc367476e 100644
--- a/net/netfilter/ipset/ip_set_hash_netnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netnet.c
@@ -170,7 +170,7 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 	u32 ip2 = 0, ip2_from = 0, ip2_to = 0;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	hash_netnet4_init(&e);
@@ -401,7 +401,7 @@ hash_netnet6_uadt(struct ip_set *set, struct nlattr *tb[],
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	hash_netnet6_init(&e);
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
index 34448df80fb9..292aeee525f9 100644
--- a/net/netfilter/ipset/ip_set_hash_netport.c
+++ b/net/netfilter/ipset/ip_set_hash_netport.c
@@ -162,7 +162,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
 	u8 cidr;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -378,7 +378,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
 	u8 cidr;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_IP] ||
diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
index 934c1712cba8..35c7b953507e 100644
--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
@@ -185,7 +185,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 	bool with_ports = false;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	hash_netportnet4_init(&e);
@@ -463,7 +463,7 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
 	bool with_ports = false;
 	int ret;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	hash_netportnet6_init(&e);
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
index cd747c0962fd..36b544c488d1 100644
--- a/net/netfilter/ipset/ip_set_list_set.c
+++ b/net/netfilter/ipset/ip_set_list_set.c
@@ -353,7 +353,7 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
 	struct ip_set *s;
 	int ret = 0;
 
-	if (tb[IPSET_ATTR_LINENO])
+	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
 	if (unlikely(!tb[IPSET_ATTR_NAME] ||
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present
  2020-01-08 10:37   ` [PATCH] " Jan Engelhardt
@ 2020-01-08 12:43     ` Kadlecsik József
  0 siblings, 0 replies; 8+ messages in thread
From: Kadlecsik József @ 2020-01-08 12:43 UTC (permalink / raw)
  To: Jan Engelhardt
  Cc: fw, netfilter-devel, netdev, syzkaller-bugs, syzbot+34bd2369d38707f3f4a7

Hi Jan,

On Wed, 8 Jan 2020, Jan Engelhardt wrote:

> The set uadt functions assume lineno is never NULL, but it is in
> case of ip_set_utest().
> 
> syzkaller managed to generate a netlink message that calls this with
> LINENO attr present:
> 
> general protection fault: 0000 [#1] PREEMPT SMP KASAN
> RIP: 0010:hash_mac4_uadt+0x1bc/0x470 net/netfilter/ipset/ip_set_hash_mac.c:104
> Call Trace:
>  ip_set_utest+0x55b/0x890 net/netfilter/ipset/ip_set_core.c:1867
>  nfnetlink_rcv_msg+0xcf2/0xfb0 net/netfilter/nfnetlink.c:229
>  netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477
>  nfnetlink_rcv+0x1ba/0x460 net/netfilter/nfnetlink.c:563
> 
> Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
> Reported-by: syzbot+34bd2369d38707f3f4a7@syzkaller.appspotmail.com
> Fixes: a7b4f989a6294 ("netfilter: ipset: IP set core support")
> Signed-off-by: Jan Engelhardt <jengelh@inai.de>
> ---
> 
>  "Pass a dummy lineno storage, its easier than patching all set
>  implementations". This may be so, but that does not mean patching
>  the implementations is much harder (does not even warrant running
>  coccinelle), so I present this alternative patch.

I really appreciate it but better fix it in one place and be done
with it. :-)

Best regards,
Jozsef
 
>  net/netfilter/ipset/ip_set_bitmap_ip.c       | 2 +-
>  net/netfilter/ipset/ip_set_bitmap_ipmac.c    | 2 +-
>  net/netfilter/ipset/ip_set_bitmap_port.c     | 2 +-
>  net/netfilter/ipset/ip_set_hash_ip.c         | 4 ++--
>  net/netfilter/ipset/ip_set_hash_ipmac.c      | 4 ++--
>  net/netfilter/ipset/ip_set_hash_ipmark.c     | 4 ++--
>  net/netfilter/ipset/ip_set_hash_ipport.c     | 4 ++--
>  net/netfilter/ipset/ip_set_hash_ipportip.c   | 4 ++--
>  net/netfilter/ipset/ip_set_hash_ipportnet.c  | 4 ++--
>  net/netfilter/ipset/ip_set_hash_mac.c        | 2 +-
>  net/netfilter/ipset/ip_set_hash_net.c        | 4 ++--
>  net/netfilter/ipset/ip_set_hash_netiface.c   | 4 ++--
>  net/netfilter/ipset/ip_set_hash_netnet.c     | 4 ++--
>  net/netfilter/ipset/ip_set_hash_netport.c    | 4 ++--
>  net/netfilter/ipset/ip_set_hash_netportnet.c | 4 ++--
>  net/netfilter/ipset/ip_set_list_set.c        | 2 +-
>  16 files changed, 27 insertions(+), 27 deletions(-)
> 
> diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c
> index abe8f77d7d23..9403730ca686 100644
> --- a/net/netfilter/ipset/ip_set_bitmap_ip.c
> +++ b/net/netfilter/ipset/ip_set_bitmap_ip.c
> @@ -137,7 +137,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
>  	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
>  	int ret = 0;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP]))
> diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
> index b618713297da..b16ebdddca83 100644
> --- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
> +++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
> @@ -248,7 +248,7 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u32 ip = 0;
>  	int ret = 0;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP]))
> diff --git a/net/netfilter/ipset/ip_set_bitmap_port.c b/net/netfilter/ipset/ip_set_bitmap_port.c
> index 23d6095cb196..cb22d85cef01 100644
> --- a/net/netfilter/ipset/ip_set_bitmap_port.c
> +++ b/net/netfilter/ipset/ip_set_bitmap_port.c
> @@ -161,7 +161,7 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u16 port_to;
>  	int ret = 0;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
> diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
> index 5d6d68eaf6a9..1195ee3539fb 100644
> --- a/net/netfilter/ipset/ip_set_hash_ip.c
> +++ b/net/netfilter/ipset/ip_set_hash_ip.c
> @@ -104,7 +104,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u32 ip = 0, ip_to = 0, hosts;
>  	int ret = 0;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP]))
> @@ -238,7 +238,7 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[],
>  	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP]))
> diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
> index eceb7bc4a93a..9a1dc251988e 100644
> --- a/net/netfilter/ipset/ip_set_hash_ipmac.c
> +++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
> @@ -126,7 +126,7 @@ hash_ipmac4_uadt(struct ip_set *set, struct nlattr *tb[],
>  		     !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBQUEUE)))
>  		return -IPSET_ERR_PROTOCOL;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &e.ip) ||
> @@ -245,7 +245,7 @@ hash_ipmac6_uadt(struct ip_set *set, struct nlattr *tb[],
>  		     !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBQUEUE)))
>  		return -IPSET_ERR_PROTOCOL;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
> diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c
> index aba1df617d6e..6b975573db7c 100644
> --- a/net/netfilter/ipset/ip_set_hash_ipmark.c
> +++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
> @@ -103,7 +103,7 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u32 ip, ip_to = 0;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] ||
> @@ -228,7 +228,7 @@ hash_ipmark6_uadt(struct ip_set *set, struct nlattr *tb[],
>  	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] ||
> diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
> index 1ff228717e29..7cec674af6de 100644
> --- a/net/netfilter/ipset/ip_set_hash_ipport.c
> +++ b/net/netfilter/ipset/ip_set_hash_ipport.c
> @@ -112,7 +112,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	bool with_ports = false;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] ||
> @@ -270,7 +270,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
>  	bool with_ports = false;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] ||
> diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
> index fa88afd812fa..9ea4b8119cbe 100644
> --- a/net/netfilter/ipset/ip_set_hash_ipportip.c
> +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
> @@ -115,7 +115,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	bool with_ports = false;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
> @@ -281,7 +281,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
>  	bool with_ports = false;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
> diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
> index eef6ecfcb409..bf089de34330 100644
> --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
> +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
> @@ -169,7 +169,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u8 cidr;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
> @@ -419,7 +419,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u8 cidr;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
> diff --git a/net/netfilter/ipset/ip_set_hash_mac.c b/net/netfilter/ipset/ip_set_hash_mac.c
> index 0b61593165ef..6cfabfedc44f 100644
> --- a/net/netfilter/ipset/ip_set_hash_mac.c
> +++ b/net/netfilter/ipset/ip_set_hash_mac.c
> @@ -100,7 +100,7 @@ hash_mac4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_ETHER] ||
> diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
> index 136cf0781d3a..3d74b249db7b 100644
> --- a/net/netfilter/ipset/ip_set_hash_net.c
> +++ b/net/netfilter/ipset/ip_set_hash_net.c
> @@ -142,7 +142,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u32 ip = 0, ip_to = 0;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] ||
> @@ -308,7 +308,7 @@ hash_net6_uadt(struct ip_set *set, struct nlattr *tb[],
>  	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] ||
> diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
> index be5e95a0d876..32fc8f794d6a 100644
> --- a/net/netfilter/ipset/ip_set_hash_netiface.c
> +++ b/net/netfilter/ipset/ip_set_hash_netiface.c
> @@ -204,7 +204,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u32 ip = 0, ip_to = 0;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] ||
> @@ -416,7 +416,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
>  	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] ||
> diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
> index da4ef910b12d..789fc367476e 100644
> --- a/net/netfilter/ipset/ip_set_hash_netnet.c
> +++ b/net/netfilter/ipset/ip_set_hash_netnet.c
> @@ -170,7 +170,7 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u32 ip2 = 0, ip2_from = 0, ip2_to = 0;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	hash_netnet4_init(&e);
> @@ -401,7 +401,7 @@ hash_netnet6_uadt(struct ip_set *set, struct nlattr *tb[],
>  	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	hash_netnet6_init(&e);
> diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
> index 34448df80fb9..292aeee525f9 100644
> --- a/net/netfilter/ipset/ip_set_hash_netport.c
> +++ b/net/netfilter/ipset/ip_set_hash_netport.c
> @@ -162,7 +162,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u8 cidr;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] ||
> @@ -378,7 +378,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
>  	u8 cidr;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_IP] ||
> diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
> index 934c1712cba8..35c7b953507e 100644
> --- a/net/netfilter/ipset/ip_set_hash_netportnet.c
> +++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
> @@ -185,7 +185,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
>  	bool with_ports = false;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	hash_netportnet4_init(&e);
> @@ -463,7 +463,7 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
>  	bool with_ports = false;
>  	int ret;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	hash_netportnet6_init(&e);
> diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
> index cd747c0962fd..36b544c488d1 100644
> --- a/net/netfilter/ipset/ip_set_list_set.c
> +++ b/net/netfilter/ipset/ip_set_list_set.c
> @@ -353,7 +353,7 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
>  	struct ip_set *s;
>  	int ret = 0;
>  
> -	if (tb[IPSET_ATTR_LINENO])
> +	if (tb[IPSET_ATTR_LINENO] != NULL && lineno != NULL)
>  		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
>  
>  	if (unlikely(!tb[IPSET_ATTR_NAME] ||
> -- 
> 2.24.1
> 
> 

-
E-mail  : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics
          H-1525 Budapest 114, POB. 49, Hungary

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: general protection fault in hash_ipportnet4_uadt
  2020-01-07 16:03 general protection fault in hash_ipportnet4_uadt syzbot
  2020-01-07 17:28 ` syzbot
  2020-01-08  9:59 ` [PATCH nf] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present Florian Westphal
@ 2020-01-08 16:53 ` syzbot
  2 siblings, 0 replies; 8+ messages in thread
From: syzbot @ 2020-01-08 16:53 UTC (permalink / raw)
  To: allison, coreteam, davem, fw, gregkh, info, jengelh, jeremy,
	kadlec, kadlec, kstewart, linux-kernel, netdev, netfilter-devel,
	pablo, syzkaller-bugs, tglx

syzbot has bisected this bug to:

commit 23c42a403a9cfdbad6004a556c927be7dd61a8ee
Author: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Date:   Sat Oct 27 13:07:40 2018 +0000

     netfilter: ipset: Introduction of new commands and protocol version 7

bisection log:  https://syzkaller.appspot.com/x/bisect.txt?x=13a9d115e00000
start commit:   ae608821 Merge tag 'trace-v5.5-rc5' of git://git.kernel.or..
git tree:       upstream
final crash:    https://syzkaller.appspot.com/x/report.txt?x=1069d115e00000
console output: https://syzkaller.appspot.com/x/log.txt?x=17a9d115e00000
kernel config:  https://syzkaller.appspot.com/x/.config?x=18698c0c240ba616
dashboard link: https://syzkaller.appspot.com/bug?extid=34bd2369d38707f3f4a7
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=118d6971e00000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=11b47c9ee00000

Reported-by: syzbot+34bd2369d38707f3f4a7@syzkaller.appspotmail.com
Fixes: 23c42a403a9c ("netfilter: ipset: Introduction of new commands and  
protocol version 7")

For information about bisection process see: https://goo.gl/tpsmEJ#bisection

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH nf] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present
  2020-01-08  9:59 ` [PATCH nf] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present Florian Westphal
  2020-01-08 10:05   ` Kadlecsik József
  2020-01-08 10:37   ` [PATCH] " Jan Engelhardt
@ 2020-01-08 22:32   ` Pablo Neira Ayuso
  2 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2020-01-08 22:32 UTC (permalink / raw)
  To: Florian Westphal
  Cc: netfilter-devel, netdev, syzkaller-bugs, Jozsef Kadlecsik,
	syzbot+34bd2369d38707f3f4a7

On Wed, Jan 08, 2020 at 10:59:38AM +0100, Florian Westphal wrote:
> The set uadt functions assume lineno is never NULL, but it is in
> case of ip_set_utest().
> 
> syzkaller managed to generate a netlink message that calls this with
> LINENO attr present:
> 
> general protection fault: 0000 [#1] PREEMPT SMP KASAN
> RIP: 0010:hash_mac4_uadt+0x1bc/0x470 net/netfilter/ipset/ip_set_hash_mac.c:104
> Call Trace:
>  ip_set_utest+0x55b/0x890 net/netfilter/ipset/ip_set_core.c:1867
>  nfnetlink_rcv_msg+0xcf2/0xfb0 net/netfilter/nfnetlink.c:229
>  netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477
>  nfnetlink_rcv+0x1ba/0x460 net/netfilter/nfnetlink.c:563
> 
> pass a dummy lineno storage, its easier than patching all set
> implementations.
> 
> This seems to be a day-0 bug.

Also applied, thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-01-08 22:32 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-07 16:03 general protection fault in hash_ipportnet4_uadt syzbot
2020-01-07 17:28 ` syzbot
2020-01-08  9:59 ` [PATCH nf] netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present Florian Westphal
2020-01-08 10:05   ` Kadlecsik József
2020-01-08 10:37   ` [PATCH] " Jan Engelhardt
2020-01-08 12:43     ` Kadlecsik József
2020-01-08 22:32   ` [PATCH nf] " Pablo Neira Ayuso
2020-01-08 16:53 ` general protection fault in hash_ipportnet4_uadt syzbot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).