Hello,
syzbot found the following crash on:
HEAD commit: 46cf053e Linux 5.5-rc3
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=11775799e00000
kernel config: https://syzkaller.appspot.com/x/.config?x=ed9d672709340e35
dashboard link: https://syzkaller.appspot.com/bug?extid=d7358a458d8a81aee898
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=13713ec1e00000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1272ba49e00000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: [email protected]
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: 9188 Comm: syz-executor670 Not tainted 5.5.0-rc3-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
RIP: 0010:__read_once_size include/linux/compiler.h:199 [inline]
RIP: 0010:net_generic include/net/netns/generic.h:45 [inline]
RIP: 0010:xt_rateest_tg_checkentry+0x11d/0xb40
net/netfilter/xt_RATEEST.c:109
Code: d9 f2 0d fb 45 84 f6 0f 84 08 07 00 00 e8 8b f1 0d fb 49 8d bd 68 13
00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f
85 f4 08 00 00 4d 8b ad 68 13 00 00 e8 cd 29 fa fa
RSP: 0018:ffffc90001df7788 EFLAGS: 00010202
RAX: dffffc0000000000 RBX: ffffc90001df7ae8 RCX: ffffffff8667437e
RDX: 000000000000026d RSI: ffffffff86673c65 RDI: 0000000000001368
RBP: ffffc90001df7848 R08: ffff888093e48540 R09: ffffed1015d2703d
R10: ffffed1015d2703c R11: ffff8880ae9381e3 R12: 000000000000002d
R13: 0000000000000000 R14: 0000000000000001 R15: ffffc90001df7820
FS: 0000000001250880(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000820 CR3: 000000008f27a000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
xt_check_target+0x283/0x690 net/netfilter/x_tables.c:1019
check_target net/ipv4/netfilter/arp_tables.c:399 [inline]
find_check_entry net/ipv4/netfilter/arp_tables.c:422 [inline]
translate_table+0x1005/0x1d70 net/ipv4/netfilter/arp_tables.c:572
do_replace net/ipv4/netfilter/arp_tables.c:977 [inline]
do_arpt_set_ctl+0x310/0x640 net/ipv4/netfilter/arp_tables.c:1456
nf_sockopt net/netfilter/nf_sockopt.c:106 [inline]
nf_setsockopt+0x77/0xd0 net/netfilter/nf_sockopt.c:115
ip_setsockopt net/ipv4/ip_sockglue.c:1260 [inline]
ip_setsockopt+0xdf/0x100 net/ipv4/ip_sockglue.c:1240
udp_setsockopt+0x68/0xb0 net/ipv4/udp.c:2639
sock_common_setsockopt+0x94/0xd0 net/core/sock.c:3149
__sys_setsockopt+0x261/0x4c0 net/socket.c:2117
__do_sys_setsockopt net/socket.c:2133 [inline]
__se_sys_setsockopt net/socket.c:2130 [inline]
__x64_sys_setsockopt+0xbe/0x150 net/socket.c:2130
do_syscall_64+0xfa/0x790 arch/x86/entry/common.c:294
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x4414d9
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:00007fff75392588 EFLAGS: 00000246 ORIG_RAX: 0000000000000036
RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 00000000004414d9
RDX: 0000000000000060 RSI: 0a02000000000000 RDI: 0000000000000003
RBP: 00000000006cb018 R08: 0000000000000530 R09: 00000000004002c8
R10: 0000000020000800 R11: 0000000000000246 R12: 0000000000402d60
R13: 0000000000402df0 R14: 0000000000000000 R15: 0000000000000000
Modules linked in:
---[ end trace 6eeb34579322f089 ]---
RIP: 0010:__read_once_size include/linux/compiler.h:199 [inline]
RIP: 0010:net_generic include/net/netns/generic.h:45 [inline]
RIP: 0010:xt_rateest_tg_checkentry+0x11d/0xb40
net/netfilter/xt_RATEEST.c:109
Code: d9 f2 0d fb 45 84 f6 0f 84 08 07 00 00 e8 8b f1 0d fb 49 8d bd 68 13
00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f
85 f4 08 00 00 4d 8b ad 68 13 00 00 e8 cd 29 fa fa
RSP: 0018:ffffc90001df7788 EFLAGS: 00010202
RAX: dffffc0000000000 RBX: ffffc90001df7ae8 RCX: ffffffff8667437e
RDX: 000000000000026d RSI: ffffffff86673c65 RDI: 0000000000001368
RBP: ffffc90001df7848 R08: ffff888093e48540 R09: ffffed1015d2703d
R10: ffffed1015d2703c R11: ffff8880ae9381e3 R12: 000000000000002d
R13: 0000000000000000 R14: 0000000000000001 R15: ffffc90001df7820
FS: 0000000001250880(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000820 CR3: 000000008f27a000 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 [email protected].
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
syzbot can test patches for this bug, for details see:
https://goo.gl/tpsmEJ#testing-patches
We get crash when the targets checkentry function tries to make
use of the network namespace pointer for arptables.
When the net pointer got added back in 2010, only ip/ip6/ebtables were
changed to initialize it, so arptables has this set to NULL.
This isn't a problem for normal arptables because no existing
arptables target has a checkentry function that makes use of par->net.
However, direct users of the setsockopt interface can provide any
target they want as long as its registered for ARP or UNPSEC protocols.
syzkaller managed to send a semi-valid arptables rule for RATEEST target
which is enough to trigger NULL deref:
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN
RIP: xt_rateest_tg_checkentry+0x11d/0xb40 net/netfilter/xt_RATEEST.c:109
[..]
xt_check_target+0x283/0x690 net/netfilter/x_tables.c:1019
check_target net/ipv4/netfilter/arp_tables.c:399 [inline]
find_check_entry net/ipv4/netfilter/arp_tables.c:422 [inline]
translate_table+0x1005/0x1d70 net/ipv4/netfilter/arp_tables.c:572
do_replace net/ipv4/netfilter/arp_tables.c:977 [inline]
do_arpt_set_ctl+0x310/0x640 net/ipv4/netfilter/arp_tables.c:1456
Fixes: add67461240c1d ("netfilter: add struct net * to target parameters")
Reported-by: [email protected]
Signed-off-by: Florian Westphal <[email protected]>
---
net/ipv4/netfilter/arp_tables.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 214154b47d56..069f72edb264 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -384,10 +384,11 @@ next: ;
return 1;
}
-static inline int check_target(struct arpt_entry *e, const char *name)
+static int check_target(struct arpt_entry *e, struct net *net, const char *name)
{
struct xt_entry_target *t = arpt_get_target(e);
struct xt_tgchk_param par = {
+ .net = net,
.table = name,
.entryinfo = e,
.target = t->u.kernel.target,
@@ -399,8 +400,9 @@ static inline int check_target(struct arpt_entry *e, const char *name)
return xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
}
-static inline int
-find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
+static int
+find_check_entry(struct arpt_entry *e, struct net *net, const char *name,
+ unsigned int size,
struct xt_percpu_counter_alloc_state *alloc_state)
{
struct xt_entry_target *t;
@@ -419,7 +421,7 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
}
t->u.kernel.target = target;
- ret = check_target(e, name);
+ ret = check_target(e, net, name);
if (ret)
goto err;
return 0;
@@ -512,7 +514,9 @@ static inline void cleanup_entry(struct arpt_entry *e)
/* Checks and translates the user-supplied table segment (held in
* newinfo).
*/
-static int translate_table(struct xt_table_info *newinfo, void *entry0,
+static int translate_table(struct net *net,
+ struct xt_table_info *newinfo,
+ void *entry0,
const struct arpt_replace *repl)
{
struct xt_percpu_counter_alloc_state alloc_state = { 0 };
@@ -569,7 +573,7 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
/* Finally, each sanity check must pass */
i = 0;
xt_entry_foreach(iter, entry0, newinfo->size) {
- ret = find_check_entry(iter, repl->name, repl->size,
+ ret = find_check_entry(iter, net, repl->name, repl->size,
&alloc_state);
if (ret != 0)
break;
@@ -974,7 +978,7 @@ static int do_replace(struct net *net, const void __user *user,
goto free_newinfo;
}
- ret = translate_table(newinfo, loc_cpu_entry, &tmp);
+ ret = translate_table(net, newinfo, loc_cpu_entry, &tmp);
if (ret != 0)
goto free_newinfo;
@@ -1149,7 +1153,8 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
}
}
-static int translate_compat_table(struct xt_table_info **pinfo,
+static int translate_compat_table(struct net *net,
+ struct xt_table_info **pinfo,
void **pentry0,
const struct compat_arpt_replace *compatr)
{
@@ -1217,7 +1222,7 @@ static int translate_compat_table(struct xt_table_info **pinfo,
repl.num_counters = 0;
repl.counters = NULL;
repl.size = newinfo->size;
- ret = translate_table(newinfo, entry1, &repl);
+ ret = translate_table(net, newinfo, entry1, &repl);
if (ret)
goto free_newinfo;
@@ -1270,7 +1275,7 @@ static int compat_do_replace(struct net *net, void __user *user,
goto free_newinfo;
}
- ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp);
+ ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
if (ret != 0)
goto free_newinfo;
@@ -1546,7 +1551,7 @@ int arpt_register_table(struct net *net,
loc_cpu_entry = newinfo->entries;
memcpy(loc_cpu_entry, repl->entries, repl->size);
- ret = translate_table(newinfo, loc_cpu_entry, repl);
+ ret = translate_table(net, newinfo, loc_cpu_entry, repl);
if (ret != 0)
goto out_free;
--
2.24.1
syzbot has bisected this bug to:
commit 3427b2ab63faccafe774ea997fc2da7faf690c5a
Author: Cong Wang <[email protected]>
Date: Fri Mar 2 02:58:38 2018 +0000
netfilter: make xt_rateest hash table per net
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=151a26c1e00000
start commit: 46cf053e Linux 5.5-rc3
git tree: upstream
final crash: https://syzkaller.appspot.com/x/report.txt?x=171a26c1e00000
console output: https://syzkaller.appspot.com/x/log.txt?x=131a26c1e00000
kernel config: https://syzkaller.appspot.com/x/.config?x=ed9d672709340e35
dashboard link: https://syzkaller.appspot.com/bug?extid=d7358a458d8a81aee898
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=13713ec1e00000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1272ba49e00000
Reported-by: [email protected]
Fixes: 3427b2ab63fa ("netfilter: make xt_rateest hash table per net")
For information about bisection process see: https://goo.gl/tpsmEJ#bisection
On Thu, Dec 26, 2019 at 6:47 PM syzbot
<[email protected]> wrote:
>
> syzbot has bisected this bug to:
>
> commit 3427b2ab63faccafe774ea997fc2da7faf690c5a
> Author: Cong Wang <[email protected]>
> Date: Fri Mar 2 02:58:38 2018 +0000
>
> netfilter: make xt_rateest hash table per net
Yes, net pointer is missing in initialization... I will send out a patch.
Thanks!
On Thu, Dec 26, 2019 at 4:37 PM Florian Westphal <[email protected]> wrote:
>
> We get crash when the targets checkentry function tries to make
> use of the network namespace pointer for arptables.
>
> When the net pointer got added back in 2010, only ip/ip6/ebtables were
> changed to initialize it, so arptables has this set to NULL.
>
> This isn't a problem for normal arptables because no existing
> arptables target has a checkentry function that makes use of par->net.
>
> However, direct users of the setsockopt interface can provide any
> target they want as long as its registered for ARP or UNPSEC protocols.
>
> syzkaller managed to send a semi-valid arptables rule for RATEEST target
> which is enough to trigger NULL deref:
>
> kasan: GPF could be caused by NULL-ptr deref or user memory access
> general protection fault: 0000 [#1] PREEMPT SMP KASAN
> RIP: xt_rateest_tg_checkentry+0x11d/0xb40 net/netfilter/xt_RATEEST.c:109
> [..]
> xt_check_target+0x283/0x690 net/netfilter/x_tables.c:1019
> check_target net/ipv4/netfilter/arp_tables.c:399 [inline]
> find_check_entry net/ipv4/netfilter/arp_tables.c:422 [inline]
> translate_table+0x1005/0x1d70 net/ipv4/netfilter/arp_tables.c:572
> do_replace net/ipv4/netfilter/arp_tables.c:977 [inline]
> do_arpt_set_ctl+0x310/0x640 net/ipv4/netfilter/arp_tables.c:1456
>
> Fixes: add67461240c1d ("netfilter: add struct net * to target parameters")
> Reported-by: [email protected]
> Signed-off-by: Florian Westphal <[email protected]>
I was about to send out a same patch.
So:
Acked-by: Cong Wang <[email protected]>
Thanks.
On Fri, Dec 27, 2019 at 01:33:10AM +0100, Florian Westphal wrote:
[...]
> kasan: GPF could be caused by NULL-ptr deref or user memory access
> general protection fault: 0000 [#1] PREEMPT SMP KASAN
> RIP: xt_rateest_tg_checkentry+0x11d/0xb40 net/netfilter/xt_RATEEST.c:109
> [..]
> xt_check_target+0x283/0x690 net/netfilter/x_tables.c:1019
> check_target net/ipv4/netfilter/arp_tables.c:399 [inline]
> find_check_entry net/ipv4/netfilter/arp_tables.c:422 [inline]
> translate_table+0x1005/0x1d70 net/ipv4/netfilter/arp_tables.c:572
> do_replace net/ipv4/netfilter/arp_tables.c:977 [inline]
> do_arpt_set_ctl+0x310/0x640 net/ipv4/netfilter/arp_tables.c:1456
Applied, thanks.