On Fri, Oct 28, 2016 at 5:40 PM, Andrey Konovalov <andreyknvl@xxxxxxxxxx> wrote: > Hi, > > I've got the following error report while running the syzkaller fuzzer: > > ------------[ cut here ]------------ > WARNING: CPU: 0 PID: 4608 at kernel/sched/core.c:7724 > __might_sleep+0x14c/0x1a0 kernel/sched/core.c:7719 > do not call blocking ops when !TASK_RUNNING; state=1 set at > [<ffffffff811f5a5c>] prepare_to_wait+0xbc/0x210 > kernel/sched/wait.c:178 > Modules linked in: > CPU: 0 PID: 4608 Comm: syz-executor Not tainted 4.9.0-rc2+ #320 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 > ffff88006625f7a0 ffffffff81b46914 ffff88006625f818 0000000000000000 > ffffffff84052960 0000000000000000 ffff88006625f7e8 ffffffff81111237 > ffff88006aceac00 ffffffff00001e2c ffffed000cc4beff ffffffff84052960 > Call Trace: > [< inline >] __dump_stack lib/dump_stack.c:15 > [<ffffffff81b46914>] dump_stack+0xb3/0x10f lib/dump_stack.c:51 > [<ffffffff81111237>] __warn+0x1a7/0x1f0 kernel/panic.c:550 > [<ffffffff8111132c>] warn_slowpath_fmt+0xac/0xd0 kernel/panic.c:565 > [<ffffffff811922fc>] __might_sleep+0x14c/0x1a0 kernel/sched/core.c:7719 > [< inline >] slab_pre_alloc_hook mm/slab.h:393 > [< inline >] slab_alloc_node mm/slub.c:2634 > [< inline >] slab_alloc mm/slub.c:2716 > [<ffffffff81508da0>] __kmalloc_track_caller+0x150/0x2a0 mm/slub.c:4240 > [<ffffffff8146be14>] kmemdup+0x24/0x50 mm/util.c:113 > [<ffffffff8388b2cf>] dccp_feat_clone_sp_val.part.5+0x4f/0xe0 > net/dccp/feat.c:374 > [< inline >] dccp_feat_clone_sp_val net/dccp/feat.c:1141 > [< inline >] dccp_feat_change_recv net/dccp/feat.c:1141 > [<ffffffff8388d491>] dccp_feat_parse_options+0xaa1/0x13d0 net/dccp/feat.c:1411 > [<ffffffff83894f01>] dccp_parse_options+0x721/0x1010 net/dccp/options.c:128 > [<ffffffff83891280>] dccp_rcv_state_process+0x200/0x15b0 net/dccp/input.c:644 > [<ffffffff838b8a94>] dccp_v4_do_rcv+0xf4/0x1a0 net/dccp/ipv4.c:681 > [< inline >] sk_backlog_rcv ./include/net/sock.h:872 > [<ffffffff82b7ceb6>] __release_sock+0x126/0x3a0 net/core/sock.c:2044 > [<ffffffff82b7d189>] release_sock+0x59/0x1c0 net/core/sock.c:2502 > [< inline >] inet_wait_for_connect net/ipv4/af_inet.c:547 > [<ffffffff8316b2a2>] __inet_stream_connect+0x5d2/0xbb0 net/ipv4/af_inet.c:617 > [<ffffffff8316b8d5>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:656 > [<ffffffff82b705e4>] SYSC_connect+0x244/0x2f0 net/socket.c:1533 > [<ffffffff82b72dd4>] SyS_connect+0x24/0x30 net/socket.c:1514 > [<ffffffff83fbf701>] entry_SYSCALL_64_fastpath+0x1f/0xc2 > arch/x86/entry/entry_64.S:209 Should be fixed the attached patch. I will verify it with your reproducer tomorrow. Thanks!
diff --git a/net/dccp/feat.c b/net/dccp/feat.c index 1704948..c90cb35 100644 --- a/net/dccp/feat.c +++ b/net/dccp/feat.c @@ -367,11 +367,11 @@ static inline int dccp_feat_must_be_understood(u8 feat_num) } /* copy constructor, fval must not already contain allocated memory */ -static int dccp_feat_clone_sp_val(dccp_feat_val *fval, u8 const *val, u8 len) +static int dccp_feat_clone_sp_val(dccp_feat_val *fval, u8 const *val, u8 len, gfp_t flags) { fval->sp.len = len; if (fval->sp.len > 0) { - fval->sp.vec = kmemdup(val, len, gfp_any()); + fval->sp.vec = kmemdup(val, len, flags); if (fval->sp.vec == NULL) { fval->sp.len = 0; return -ENOBUFS; @@ -404,7 +404,8 @@ static void dccp_feat_val_destructor(u8 feat_num, dccp_feat_val *val) if (type == FEAT_SP && dccp_feat_clone_sp_val(&new->val, original->val.sp.vec, - original->val.sp.len)) { + original->val.sp.len, + gfp_any())) { kfree(new); return NULL; } @@ -735,7 +736,7 @@ static int __feat_register_sp(struct list_head *fn, u8 feat, u8 is_local, if (feat == DCCPF_CCID && !ccid_support_check(sp_val, sp_len)) return -EOPNOTSUPP; - if (dccp_feat_clone_sp_val(&fval, sp_val, sp_len)) + if (dccp_feat_clone_sp_val(&fval, sp_val, sp_len, gfp_any())) return -ENOMEM; return dccp_feat_push_change(fn, feat, is_local, mandatory, &fval); @@ -1138,7 +1139,7 @@ static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt, * otherwise we accept the preferred value; * - else if we are the client, we use the first list element. */ - if (dccp_feat_clone_sp_val(&fval, val, 1)) + if (dccp_feat_clone_sp_val(&fval, val, 1, GFP_ATOMIC)) return DCCP_RESET_CODE_TOO_BUSY; if (len > 1 && server) {