From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0624B143C4B; Tue, 27 Feb 2024 14:27:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709044062; cv=none; b=rxGwd0usrnGFJzKzdJRjC3w2Jn06ECCLdRy8dl1uNQT85UYG1a0eDVZJ9is3wV5ccitoShJmwdRzIOYGAyEGomLSeC+Y4DWqq/tQp9Mf6aUVSvvKH7e+b7phqP2xYkBWhElid7w1JuuCquOg4FIJMrHKjJEGI/QlkJ7aZWZpTPg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709044062; c=relaxed/simple; bh=yrhieljzMk5MiA4Wz5ziTw91/VSDtHSF38onAsQ3H4U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KYJTVyA2REFkTZZbIPIv9iw4Hkfwkkduxc7an0U+/6BshLeYYqTk6BoJcQ+zyJRM5MHrEyKvJzuhQl7hGIFfiuZqnY5wSfCFmDncSnxSMwHLdBAERrdIBNtW5d7eqhoknCHy986p8K7zOdLzKykfqGvsbOKQf/k7k7z+IgwBdNw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=XaZrzVPL; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="XaZrzVPL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85D90C433C7; Tue, 27 Feb 2024 14:27:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1709044061; bh=yrhieljzMk5MiA4Wz5ziTw91/VSDtHSF38onAsQ3H4U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XaZrzVPLORxfIFmQue0GqlCiTA5m8gv8YQnfdUH2bJxD2yEPOCxYzNb0w87hMOK3L AtKNr2obhAB58MjL2JG350dDd4YLwkgqxU0N+HtaMmsv2FTlZmp3I+G+WI2ktjUbms +Dh2MaBMZ0g2XOoKu7I0iPPT9O0H9DN5CAxTGdl8= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Sebastian Andrzej Siewior , Jakub Kicinski , Sasha Levin Subject: [PATCH 5.10 049/122] hsr: Avoid double remove of a node. Date: Tue, 27 Feb 2024 14:26:50 +0100 Message-ID: <20240227131600.313447574@linuxfoundation.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240227131558.694096204@linuxfoundation.org> References: <20240227131558.694096204@linuxfoundation.org> User-Agent: quilt/0.67 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: Sebastian Andrzej Siewior [ Upstream commit 0c74d9f79ec4299365bbe803baa736ae0068179e ] Due to the hashed-MAC optimisation one problem become visible: hsr_handle_sup_frame() walks over the list of available nodes and merges two node entries into one if based on the information in the supervision both MAC addresses belong to one node. The list-walk happens on a RCU protected list and delete operation happens under a lock. If the supervision arrives on both slave interfaces at the same time then this delete operation can occur simultaneously on two CPUs. The result is the first-CPU deletes the from the list and the second CPUs BUGs while attempting to dereference a poisoned list-entry. This happens more likely with the optimisation because a new node for the mac_B entry is created once a packet has been received and removed (merged) once the supervision frame has been received. Avoid removing/ cleaning up a hsr_node twice by adding a `removed' field which is set to true after the removal and checked before the removal. Fixes: f266a683a4804 ("net/hsr: Better frame dispatch") Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/hsr/hsr_framereg.c | 16 +++++++++++----- net/hsr/hsr_framereg.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c index afc97d65cf2d8..87fc86aade5c9 100644 --- a/net/hsr/hsr_framereg.c +++ b/net/hsr/hsr_framereg.c @@ -327,9 +327,12 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame) node_real->addr_B_port = port_rcv->type; spin_lock_bh(&hsr->list_lock); - list_del_rcu(&node_curr->mac_list); + if (!node_curr->removed) { + list_del_rcu(&node_curr->mac_list); + node_curr->removed = true; + kfree_rcu(node_curr, rcu_head); + } spin_unlock_bh(&hsr->list_lock); - kfree_rcu(node_curr, rcu_head); done: /* PRP uses v0 header */ @@ -506,9 +509,12 @@ void hsr_prune_nodes(struct timer_list *t) if (time_is_before_jiffies(timestamp + msecs_to_jiffies(HSR_NODE_FORGET_TIME))) { hsr_nl_nodedown(hsr, node->macaddress_A); - list_del_rcu(&node->mac_list); - /* Note that we need to free this entry later: */ - kfree_rcu(node, rcu_head); + if (!node->removed) { + list_del_rcu(&node->mac_list); + node->removed = true; + /* Note that we need to free this entry later: */ + kfree_rcu(node, rcu_head); + } } } spin_unlock_bh(&hsr->list_lock); diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h index 5a771cb3f0325..48990166e4c4e 100644 --- a/net/hsr/hsr_framereg.h +++ b/net/hsr/hsr_framereg.h @@ -82,6 +82,7 @@ struct hsr_node { bool san_a; bool san_b; u16 seq_out[HSR_PT_PORTS]; + bool removed; struct rcu_head rcu_head; }; -- 2.43.0