Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp261546img; Mon, 18 Mar 2019 02:31:21 -0700 (PDT) X-Google-Smtp-Source: APXvYqwiQ3o2aCeFjzXo6PaRZxHPbcMeVnTrWLvgi+XiOrPkfwhckc4xUGC5wPI4NM2hBxeDl4JO X-Received: by 2002:a62:3681:: with SMTP id d123mr18222358pfa.242.1552901481589; Mon, 18 Mar 2019 02:31:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1552901481; cv=none; d=google.com; s=arc-20160816; b=qqDKAA7ZEVqlbOCdZ3p046O9N3bP3B0NXC0UgagNsGCfjFA7j0Np5gj41cngx6humK QRSdVqI6FsR9RQF4DV+akXh3WKnwG0IbrasFk6Cc2f6/8cRwwueOK1uuU6DMjM84xPUm Vb2TZ1rAJui3kA9r6f5VOXIiip5sNqbFuQXHZ42ePiwrGAiFRqKV2a1DFASd+gWBr5lO +nSpcT+7sPRVnIxHxELcgDaPMGR1P6i8JvsW3zoj3Tof6ARnje8vNtCFcNSpANnYNyhr Lhcm8xLqTzybOe/+vJSe3Lux72b8upfIAtq2xqHsKcfCMnA09tzvJkW0MJXAbJPe1FcE PtxQ== 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=Zc/tgHRzOBLOSZFk3jsFxBPxMCVtLC8GCiPL/6rEC6Y=; b=bicvXXSP8x3OKyAci/CjH4ga0630YeYRVszPNPi72tPbaIGUEfwPvDrNu/590NvCBL yIJ/wqW8MUIyyeZIQUFR7k+qZgoBTSs4Lk8aEykEXO4414bK43nfppU73lKxHVQaTj93 bJlY6iuXWU/jak8Rov/VVJ70MILUWr4aVTPKJB7JtMKm3ACp/HzSBU/ntfVAFCHHja9n EMeWBE/TIcmGDNdTowwNQwtYU0P5n4T19yGL1V+HFBs08W+3B2Hx+Jj489G7JjxNxd/m qshBscYQ/i9/DyTqwcQeTAfkpceXYvpMqnFO1MZ/kOr2q0PBCgIgrTWqF748iLBOlNBO UvNA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=wXIo25H9; 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 s14si8489147pgs.98.2019.03.18.02.31.06; Mon, 18 Mar 2019 02:31:21 -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; dkim=pass header.i=@kernel.org header.s=default header.b=wXIo25H9; 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 S1728273AbfCRJ3m (ORCPT + 99 others); Mon, 18 Mar 2019 05:29:42 -0400 Received: from mail.kernel.org ([198.145.29.99]:36156 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727890AbfCRJ3i (ORCPT ); Mon, 18 Mar 2019 05:29:38 -0400 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 0DD272075C; Mon, 18 Mar 2019 09:29:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1552901377; bh=Fx5ZOmlCRhZS+0XL4m+orrxmjLXfrNjwMmPA0HzuEe8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wXIo25H98qGsX8MsHBGWE9LIGZbw7F5Z52q/U16HFELfbbrqjWYTdbAVv1QWAqsmN SHyU7zmvX2yqiHV2PWSdePCYsCM6aQX1Rmh3vcVRuhdIXQBXBPMDRySGPrdSeuSiFe DIhXcBt1lDj162tGrXvr+XDjS+DrFa30W9tDDsUw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Vlad Buslov , Roi Dayan , "David S. Miller" Subject: [PATCH 4.20 26/52] net: sched: flower: insert new filter to idr after setting its mask Date: Mon, 18 Mar 2019 10:25:13 +0100 Message-Id: <20190318083846.541755610@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190318083843.398913295@linuxfoundation.org> References: <20190318083843.398913295@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: Vlad Buslov [ Upstream commit ecb3dea400d3beaf611ce76ac7a51d4230492cf2 ] When adding new filter to flower classifier, fl_change() inserts it to handle_idr before initializing filter extensions and assigning it a mask. Normally this ordering doesn't matter because all flower classifier ops callbacks assume rtnl lock protection. However, when filter has an action that doesn't have its kernel module loaded, rtnl lock is released before call to request_module(). During this time the filter can be accessed bu concurrent task before its initialization is completed, which can lead to a crash. Example case of NULL pointer dereference in concurrent dump: Task 1 Task 2 tc_new_tfilter() fl_change() idr_alloc_u32(fnew) fl_set_parms() tcf_exts_validate() tcf_action_init() tcf_action_init_1() rtnl_unlock() request_module() ... rtnl_lock() tc_dump_tfilter() tcf_chain_dump() fl_walk() idr_get_next_ul() tcf_node_dump() tcf_fill_node() fl_dump() mask = &f->mask->key; <- NULL ptr rtnl_lock() Extension initialization and mask assignment don't depend on fnew->handle that is allocated by idr_alloc_u32(). Move idr allocation code after action creation and mask assignment in fl_change() to prevent concurrent access to not fully initialized filter when rtnl lock is released to load action module. Fixes: 01683a146999 ("net: sched: refactor flower walk to iterate over idr") Signed-off-by: Vlad Buslov Reviewed-by: Roi Dayan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sched/cls_flower.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -1213,46 +1213,46 @@ static int fl_change(struct net *net, st if (err < 0) goto errout; - if (!handle) { - handle = 1; - err = idr_alloc_u32(&head->handle_idr, fnew, &handle, - INT_MAX, GFP_KERNEL); - } else if (!fold) { - /* user specifies a handle and it doesn't exist */ - err = idr_alloc_u32(&head->handle_idr, fnew, &handle, - handle, GFP_KERNEL); - } - if (err) - goto errout; - fnew->handle = handle; - if (tb[TCA_FLOWER_FLAGS]) { fnew->flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]); if (!tc_flags_valid(fnew->flags)) { err = -EINVAL; - goto errout_idr; + goto errout; } } err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], ovr, tp->chain->tmplt_priv, extack); if (err) - goto errout_idr; + goto errout; err = fl_check_assign_mask(head, fnew, fold, mask); if (err) - goto errout_idr; + goto errout; + + if (!handle) { + handle = 1; + err = idr_alloc_u32(&head->handle_idr, fnew, &handle, + INT_MAX, GFP_KERNEL); + } else if (!fold) { + /* user specifies a handle and it doesn't exist */ + err = idr_alloc_u32(&head->handle_idr, fnew, &handle, + handle, GFP_KERNEL); + } + if (err) + goto errout_mask; + fnew->handle = handle; if (!fold && fl_lookup(fnew->mask, &fnew->mkey)) { err = -EEXIST; - goto errout_mask; + goto errout_idr; } err = rhashtable_insert_fast(&fnew->mask->ht, &fnew->ht_node, fnew->mask->filter_ht_params); if (err) - goto errout_mask; + goto errout_idr; if (!tc_skip_hw(fnew->flags)) { err = fl_hw_replace_filter(tp, fnew, extack); @@ -1291,12 +1291,13 @@ errout_mask_ht: rhashtable_remove_fast(&fnew->mask->ht, &fnew->ht_node, fnew->mask->filter_ht_params); -errout_mask: - fl_mask_put(head, fnew->mask, false); - errout_idr: if (!fold) idr_remove(&head->handle_idr, fnew->handle); + +errout_mask: + fl_mask_put(head, fnew->mask, false); + errout: tcf_exts_destroy(&fnew->exts); kfree(fnew);