Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp723235imm; Thu, 13 Sep 2018 06:51:13 -0700 (PDT) X-Google-Smtp-Source: ANB0VdaHUoQgmjSirCJ1M8pfAto+nw+SUGb1xhjKZa9COBffCMz23FIkFhNrJPxPoNhK/1rc2gn3 X-Received: by 2002:a62:fcd2:: with SMTP id e201-v6mr7667199pfh.101.1536846673427; Thu, 13 Sep 2018 06:51:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536846673; cv=none; d=google.com; s=arc-20160816; b=Teb9mhmiOTacnpQxgrgzI4Qiit9naDHNFB27M57nBsh+CP50PXpVT69d9NdPXKDZw+ F2P5kE6spZxBephYTPmOx7pao5bYFXdiWXhahQYFQEAUpC4I1/NFmUGco32/8zfBmhp1 Ohk0zUxR1xx/SyNeWdFeaDbqlb4pD/Adqv9yyzkNnz0rHr65HvQ6ux2+5dwhXYXZydZD sApGvoNMExm/6nAUVyskMYcarkmT34MX4PXnUIOC2YS2FyfqHgas+fkKNrjpTQPndikm j7ePBNlGmtSJ9HfIdLs39cI3KaCBwpV6FeIvq++PFLvkKvdqUk6F9RodsEHXK5XYpxNI 22KA== 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; bh=SuT/bNm4lV5ss1B65Wy5QiPpw0E8xn3Keiy/cCxegJo=; b=mNkjiz2phWNhB+dWpI3kCWK0K+qZ1o8SHSMzR/fsQ0177vW/YVu/rgYUJhZKuK9oIi q5VdGcUx77IAUV4nZKpFfwxbco2NW8mvFMrMh33O/UBNaX/IRsNv6i2OGuaZNedOkB7J DC9wQHrxF2tvOh6wnptPUlfzX3zZQjjtgDUvkycC5i/rPhTCPG23680RgtJtLLJ26j13 aEPZ4XlzIrXa2bhf7JJYF+9IFIuC7R+r5Wxe538+k7xPhPEj/hPI0n2mVRl0HHPo3lg4 bhcCuLZg7FpjUcu1IXdlWlCdhTpECK7m+i17Io2hljNH7iFJ9zDpk89EyHwifXSDe6t0 TR1g== ARC-Authentication-Results: i=1; mx.google.com; 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 o23-v6si3876221pgv.518.2018.09.13.06.50.58; Thu, 13 Sep 2018 06:51:13 -0700 (PDT) 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; 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 S1730720AbeIMTAC (ORCPT + 99 others); Thu, 13 Sep 2018 15:00:02 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:33172 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730489AbeIMTAC (ORCPT ); Thu, 13 Sep 2018 15:00:02 -0400 Received: from localhost (ip-213-127-77-73.ip.prioritytelecom.net [213.127.77.73]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id EBE8CCFE; Thu, 13 Sep 2018 13:50:26 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jamal Hadi Salim , Cong Wang , "David S. Miller" Subject: [PATCH 4.18 012/197] act_ife: fix a potential deadlock Date: Thu, 13 Sep 2018 15:29:21 +0200 Message-Id: <20180913131842.059089208@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180913131841.568116777@linuxfoundation.org> References: <20180913131841.568116777@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review 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.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Cong Wang [ Upstream commit 5ffe57da29b3802baeddaa40909682bbb4cb4d48 ] use_all_metadata() acquires read_lock(&ife_mod_lock), then calls add_metainfo() which calls find_ife_oplist() which acquires the same lock again. Deadlock! Introduce __add_metainfo() which accepts struct tcf_meta_ops *ops as an additional parameter and let its callers to decide how to find it. For use_all_metadata(), it already has ops, no need to find it again, just call __add_metainfo() directly. And, as ife_mod_lock is only needed for find_ife_oplist(), this means we can make non-atomic allocation for populate_metalist() now. Fixes: 817e9f2c5c26 ("act_ife: acquire ife_mod_lock before reading ifeoplist") Cc: Jamal Hadi Salim Signed-off-by: Cong Wang Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sched/act_ife.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c @@ -294,22 +294,16 @@ static int load_metaops_and_vet(u32 meta /* called when adding new meta information */ -static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, - int len, bool atomic, bool exists) +static int __add_metainfo(const struct tcf_meta_ops *ops, + struct tcf_ife_info *ife, u32 metaid, void *metaval, + int len, bool atomic, bool exists) { struct tcf_meta_info *mi = NULL; - struct tcf_meta_ops *ops = find_ife_oplist(metaid); int ret = 0; - if (!ops) - return -ENOENT; - mi = kzalloc(sizeof(*mi), atomic ? GFP_ATOMIC : GFP_KERNEL); - if (!mi) { - /*put back what find_ife_oplist took */ - module_put(ops->owner); + if (!mi) return -ENOMEM; - } mi->metaid = metaid; mi->ops = ops; @@ -317,7 +311,6 @@ static int add_metainfo(struct tcf_ife_i ret = ops->alloc(mi, metaval, atomic ? GFP_ATOMIC : GFP_KERNEL); if (ret != 0) { kfree(mi); - module_put(ops->owner); return ret; } } @@ -331,6 +324,21 @@ static int add_metainfo(struct tcf_ife_i return ret; } +static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, + int len, bool exists) +{ + const struct tcf_meta_ops *ops = find_ife_oplist(metaid); + int ret; + + if (!ops) + return -ENOENT; + ret = __add_metainfo(ops, ife, metaid, metaval, len, false, exists); + if (ret) + /*put back what find_ife_oplist took */ + module_put(ops->owner); + return ret; +} + static int use_all_metadata(struct tcf_ife_info *ife, bool exists) { struct tcf_meta_ops *o; @@ -339,7 +347,7 @@ static int use_all_metadata(struct tcf_i read_lock(&ife_mod_lock); list_for_each_entry(o, &ifeoplist, list) { - rc = add_metainfo(ife, o->metaid, NULL, 0, true, exists); + rc = __add_metainfo(o, ife, o->metaid, NULL, 0, true, exists); if (rc == 0) installed += 1; } @@ -433,7 +441,7 @@ static int populate_metalist(struct tcf_ if (rc != 0) return rc; - rc = add_metainfo(ife, i, val, len, false, exists); + rc = add_metainfo(ife, i, val, len, exists); if (rc) return rc; }