Received: by 2002:ac0:b08d:0:0:0:0:0 with SMTP id l13csp4920252imc; Mon, 25 Feb 2019 13:39:38 -0800 (PST) X-Google-Smtp-Source: AHgI3IZ4nG6HKXUdPsp1xIg92nltzJ3LeOFyxvKBL8hL1LWcau9h65/qzUrrWVLr+2ywEB1PyNw7 X-Received: by 2002:a62:64d1:: with SMTP id y200mr20800107pfb.161.1551130778676; Mon, 25 Feb 2019 13:39:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551130778; cv=none; d=google.com; s=arc-20160816; b=LoftPUXIZMLypV/ZkYPqUkU7RiT6t9F48wRzNQPiGUQockt0J+CU1Y0M2Fh7ijG8wt 6g/iFPWAz1QQFptdzZhxXLuF/Gw93WKWBimfE2tukimq/zJjrzfySJumN8LJ8TeUb1DF +28ydYy7J4mV2VVNclIRzWtnLYbgbx3w4cU5V1z5UP2NwqR2qd/FH3ck07jROTcgZ2bx KzoiSP+tSYYZDub3mGxyBU3MlAQ7BAunE/lNQFLT8fbBS4CWCcd01OXiT/IzB6aNo6ef 20SOBySCgxNRh66YY/9A921Xz4KT/iRMf4QeqGwWmn25kzS4fYAj8kt+hXFa+oHIlZGj GZxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=ySamvI0SKasDai3Hawu7bpxC4sW+LX63aI0numZx76A=; b=uYpqD5euzMjkkWDDKVb1CA7UJa9HZm5WjgOMCt/+z5zX9CsVJHQ/T5pzxtyBtKs9vf uN0zR4ja+c/UOL3yDZ3PURfnm+GAJYi8UbMRcNDHilwrl3VIY8s9kFGpF3Difiru/qbF 7pjMjA2flPZzm/p1Y1scSJ8yJqnpZlbVKRQSgtfOujpQW5fr72w3JFOux2KRXcFfAJoo VIWBNz5f8IhWj2coBqczafNjAjWG7U2HTaADXYjDT90cwiJuQAsDdR4ivKyiBDvqZca1 /4W+zHK5Du7KS7HBavIANbBdCag6KwzFL4v27FgoHwanaEVZ0EqImlhBT7Vb1cQ60FKO BzjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=1VDt8QhX; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d37si10448006pgb.226.2019.02.25.13.39.23; Mon, 25 Feb 2019 13:39:38 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=1VDt8QhX; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387496AbfBYVhh (ORCPT + 99 others); Mon, 25 Feb 2019 16:37:37 -0500 Received: from mail.kernel.org ([198.145.29.99]:44678 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387481AbfBYVhe (ORCPT ); Mon, 25 Feb 2019 16:37:34 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id ECE3220578; Mon, 25 Feb 2019 21:37:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1551130653; bh=ighz6dUZ+uMF0GLJrVmwTn9tUQDZieSvRnG9pqfewAU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1VDt8QhXJ6uqpj8Mw8k4Xf17ijbXAymj0q6jeN9dcIjNcczX9h+7p3Q1ePxyshnmL uUT4i055OKdjYD2ogKs7QAd7+v2EokzmSlZtXIK9OeSKmIIS89euczoQ25pSO5/OGq 3PVKqsHp3RNAW0HECIPQHqj3lwSWzQZKK4FqeFrM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Taehee Yoo , Pablo Neira Ayuso Subject: [PATCH 4.20 182/183] netfilter: ipt_CLUSTERIP: fix sleep-in-atomic bug in clusterip_config_entry_put() Date: Mon, 25 Feb 2019 22:12:35 +0100 Message-Id: <20190225195125.860200962@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225195054.748060397@linuxfoundation.org> References: <20190225195054.748060397@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.20-stable review patch. If anyone has any objections, please let me know. ------------------ From: Taehee Yoo commit 2a61d8b883bbad26b06d2e6cc3777a697e78830d upstream. A proc_remove() can sleep. so that it can't be inside of spin_lock. Hence proc_remove() is moved to outside of spin_lock. and it also adds mutex to sync create and remove of proc entry(config->pde). test commands: SHELL#1 %while :; do iptables -A INPUT -p udp -i enp2s0 -d 192.168.1.100 \ --dport 9000 -j CLUSTERIP --new --hashmode sourceip \ --clustermac 01:00:5e:00:00:21 --total-nodes 3 --local-node 3; \ iptables -F; done SHELL#2 %while :; do echo +1 > /proc/net/ipt_CLUSTERIP/192.168.1.100; \ echo -1 > /proc/net/ipt_CLUSTERIP/192.168.1.100; done [ 2949.569864] BUG: sleeping function called from invalid context at kernel/sched/completion.c:99 [ 2949.579944] in_atomic(): 1, irqs_disabled(): 0, pid: 5472, name: iptables [ 2949.587920] 1 lock held by iptables/5472: [ 2949.592711] #0: 000000008f0ebcf2 (&(&cn->lock)->rlock){+...}, at: refcount_dec_and_lock+0x24/0x50 [ 2949.603307] CPU: 1 PID: 5472 Comm: iptables Tainted: G W 4.19.0-rc5+ #16 [ 2949.604212] Hardware name: To be filled by O.E.M. To be filled by O.E.M./Aptio CRB, BIOS 5.6.5 07/08/2015 [ 2949.604212] Call Trace: [ 2949.604212] dump_stack+0xc9/0x16b [ 2949.604212] ? show_regs_print_info+0x5/0x5 [ 2949.604212] ___might_sleep+0x2eb/0x420 [ 2949.604212] ? set_rq_offline.part.87+0x140/0x140 [ 2949.604212] ? _rcu_barrier_trace+0x400/0x400 [ 2949.604212] wait_for_completion+0x94/0x710 [ 2949.604212] ? wait_for_completion_interruptible+0x780/0x780 [ 2949.604212] ? __kernel_text_address+0xe/0x30 [ 2949.604212] ? __lockdep_init_map+0x10e/0x5c0 [ 2949.604212] ? __lockdep_init_map+0x10e/0x5c0 [ 2949.604212] ? __init_waitqueue_head+0x86/0x130 [ 2949.604212] ? init_wait_entry+0x1a0/0x1a0 [ 2949.604212] proc_entry_rundown+0x208/0x270 [ 2949.604212] ? proc_reg_get_unmapped_area+0x370/0x370 [ 2949.604212] ? __lock_acquire+0x4500/0x4500 [ 2949.604212] ? complete+0x18/0x70 [ 2949.604212] remove_proc_subtree+0x143/0x2a0 [ 2949.708655] ? remove_proc_entry+0x390/0x390 [ 2949.708655] clusterip_tg_destroy+0x27a/0x630 [ipt_CLUSTERIP] [ ... ] Fixes: b3e456fce9f5 ("netfilter: ipt_CLUSTERIP: fix a race condition of proc file creation") Signed-off-by: Taehee Yoo Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- net/ipv4/netfilter/ipt_CLUSTERIP.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -56,7 +56,7 @@ struct clusterip_config { #endif enum clusterip_hashmode hash_mode; /* which hashing mode */ u_int32_t hash_initval; /* hash initialization */ - struct rcu_head rcu; + struct rcu_head rcu; /* for call_rcu_bh */ struct net *net; /* netns for pernet list */ char ifname[IFNAMSIZ]; /* device ifname */ }; @@ -72,6 +72,8 @@ struct clusterip_net { #ifdef CONFIG_PROC_FS struct proc_dir_entry *procdir; + /* mutex protects the config->pde*/ + struct mutex mutex; #endif }; @@ -118,17 +120,18 @@ clusterip_config_entry_put(struct cluste local_bh_disable(); if (refcount_dec_and_lock(&c->entries, &cn->lock)) { + list_del_rcu(&c->list); + spin_unlock(&cn->lock); + local_bh_enable(); /* In case anyone still accesses the file, the open/close * functions are also incrementing the refcount on their own, * so it's safe to remove the entry even if it's in use. */ #ifdef CONFIG_PROC_FS + mutex_lock(&cn->mutex); if (cn->procdir) proc_remove(c->pde); + mutex_unlock(&cn->mutex); #endif - list_del_rcu(&c->list); - spin_unlock(&cn->lock); - local_bh_enable(); - return; } local_bh_enable(); @@ -278,9 +281,11 @@ clusterip_config_init(struct net *net, c /* create proc dir entry */ sprintf(buffer, "%pI4", &ip); + mutex_lock(&cn->mutex); c->pde = proc_create_data(buffer, 0600, cn->procdir, &clusterip_proc_fops, c); + mutex_unlock(&cn->mutex); if (!c->pde) { err = -ENOMEM; goto err; @@ -833,6 +838,7 @@ static int clusterip_net_init(struct net pr_err("Unable to proc dir entry\n"); return -ENOMEM; } + mutex_init(&cn->mutex); #endif /* CONFIG_PROC_FS */ return 0; @@ -841,9 +847,12 @@ static int clusterip_net_init(struct net static void clusterip_net_exit(struct net *net) { struct clusterip_net *cn = clusterip_pernet(net); + #ifdef CONFIG_PROC_FS + mutex_lock(&cn->mutex); proc_remove(cn->procdir); cn->procdir = NULL; + mutex_unlock(&cn->mutex); #endif nf_unregister_net_hook(net, &cip_arp_ops); }