Re: net/dccp: warning in dccp_feat_clone_sp_val/__might_sleep

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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) {

[Index of Archives]     [Linux Kernel]     [IETF DCCP]     [Linux Networking]     [Git]     [Security]     [Linux Assembly]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux