From patchwork Mon May 16 19:36:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 573273 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 20B5CC433EF for ; Mon, 16 May 2022 20:08:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236718AbiEPUIb (ORCPT ); Mon, 16 May 2022 16:08:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350180AbiEPUAx (ORCPT ); Mon, 16 May 2022 16:00:53 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 45DE246678; Mon, 16 May 2022 12:55:04 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id EADAB60EC5; Mon, 16 May 2022 19:54:38 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DC574C385AA; Mon, 16 May 2022 19:54:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1652730878; bh=JmpcYXscK83DlcoDFesJzDB+yzA4kDzMTLDl4wun3Rw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ohrXyAK7I4o6WtzKd0DDtboiP6yCVe5OXfj2RyxPcpYTpddGF3aCrvWbprLgMAVL0 7GiMDcvyojUj66Ep+2Xze0rmfgYayjXUosGyRXymEwc3LXhWrbaG2CGRV9T7D6vCZJ tRNSKRDP2ugHkmq0xTsxCn7LwtHebkrSbLshVXoo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Vladimir Oltean , Jakub Kicinski , Sasha Levin Subject: [PATCH 5.17 032/114] net: dsa: flush switchdev workqueue on bridge join error path Date: Mon, 16 May 2022 21:36:06 +0200 Message-Id: <20220516193626.413082272@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516193625.489108457@linuxfoundation.org> References: <20220516193625.489108457@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Vladimir Oltean [ Upstream commit 630fd4822af2374cd75c682b7665dcb367613765 ] There is a race between switchdev_bridge_port_offload() and the dsa_port_switchdev_sync_attrs() call right below it. When switchdev_bridge_port_offload() finishes, FDB entries have been replayed by the bridge, but are scheduled for deferred execution later. However dsa_port_switchdev_sync_attrs -> dsa_port_can_apply_vlan_filtering() may impose restrictions on the vlan_filtering attribute and refuse offloading. When this happens, the delayed FDB entries will dereference dp->bridge, which is a NULL pointer because we have stopped the process of offloading this bridge. Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 Workqueue: dsa_ordered dsa_slave_switchdev_event_work pc : dsa_port_bridge_host_fdb_del+0x64/0x100 lr : dsa_slave_switchdev_event_work+0x130/0x1bc Call trace: dsa_port_bridge_host_fdb_del+0x64/0x100 dsa_slave_switchdev_event_work+0x130/0x1bc process_one_work+0x294/0x670 worker_thread+0x80/0x460 ---[ end trace 0000000000000000 ]--- Error: dsa_core: Must first remove VLAN uppers having VIDs also present in bridge. Fix the bug by doing what we do on the normal bridge leave path as well, which is to wait until the deferred FDB entries complete executing, then exit. The placement of dsa_flush_workqueue() after switchdev_bridge_port_unoffload() guarantees that both the FDB additions and deletions on rollback are waited for. Fixes: d7d0d423dbaa ("net: dsa: flush switchdev workqueue when leaving the bridge") Signed-off-by: Vladimir Oltean Link: https://lore.kernel.org/r/20220507134550.1849834-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/dsa/port.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/dsa/port.c b/net/dsa/port.c index 4368fd32c4a5..f4bd063f8315 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -367,6 +367,7 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, switchdev_bridge_port_unoffload(brport_dev, dp, &dsa_slave_switchdev_notifier, &dsa_slave_switchdev_blocking_notifier); + dsa_flush_workqueue(); out_rollback_unbridge: dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info); out_rollback: