From nobody Wed Oct 8 02:00:44 2025 Received: from szxga05-in.huawei.com (szxga05-in.huawei.com [45.249.212.191]) (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 7689C29B783; Thu, 3 Jul 2025 07:54:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.191 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751529269; cv=none; b=RswG9GqyfjgF6VQnAI3tfVfcKaq6RD99l2n+5ILJnjYyvKaTG4URkem3wRx0Scvmrdmf4OxtQ+PJlHG3z3wNZHuXUi91pOBkZ29/M2cddtdNRCzlkZwC002pabmS9urWAVxVUdyUUbllJrikkkzkOTN+i43YuXheUWbp6iCKrHc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751529269; c=relaxed/simple; bh=lt+M87RByfReAxvdmnUfBWNo3o235T3tR6JtwxzdkGI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=kz6r4CdWLgrtMRsjWW3rBq9zqqVQdIGmgJ0mVkpPXOcB8HvhXQ7n8W/jXby+nmeOhk//zTqlQzR8KnJh/KLGf9z1bDaoMA/9pBohYOkSWu8U9OZJ0WbwKIZFJZle7PzUYq8zu3kxKFkdBy6K5DE3pCxVb1GeGxPmllIOxOzlo5g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.191 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.214]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4bXpr70gs8z1R8fv; Thu, 3 Jul 2025 15:51:51 +0800 (CST) Received: from dggemv712-chm.china.huawei.com (unknown [10.1.198.32]) by mail.maildlp.com (Postfix) with ESMTPS id 8903E1A016C; Thu, 3 Jul 2025 15:54:22 +0800 (CST) Received: from kwepemq200002.china.huawei.com (7.202.195.90) by dggemv712-chm.china.huawei.com (10.1.198.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Thu, 3 Jul 2025 15:54:22 +0800 Received: from localhost.localdomain (10.175.104.82) by kwepemq200002.china.huawei.com (7.202.195.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Thu, 3 Jul 2025 15:54:21 +0800 From: Dong Chenchen To: , , , , , , , , , CC: , , Subject: [PATCH net v2 1/2] net: vlan: fix VLAN 0 refcount imbalance of toggling filtering during runtime Date: Thu, 3 Jul 2025 15:57:01 +0800 Message-ID: <20250703075702.1063149-2-dongchenchen2@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250703075702.1063149-1-dongchenchen2@huawei.com> References: <20250703075702.1063149-1-dongchenchen2@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems200001.china.huawei.com (7.221.188.67) To kwepemq200002.china.huawei.com (7.202.195.90) Content-Type: text/plain; charset="utf-8" 8021q(vlan_device_event) will add VLAN 0 when enabling the device, and remove it on disabling it if NETIF_F_HW_VLAN_CTAG_FILTER set. However, if changing filter feature during netdev runtime, null-ptr-unref[1] or bug_on[2] will be triggered by unregister_vlan_dev() for refcount imbalance. [1] BUG: KASAN: null-ptr-deref in unregister_vlan_dev (net/8021q/vlan.h:90 net/= 8021q/vlan.c:110) Write of size 8 at addr 0000000000000000 by task ip/382 CPU: 2 UID: 0 PID: 382 Comm: ip Not tainted 6.16.0-rc3 #60 PREEMPT(voluntar= y) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 Call Trace: dump_stack_lvl (lib/dump_stack.c:123) kasan_report (mm/kasan/report.c:636) unregister_vlan_dev (net/8021q/vlan.h:90 net/8021q/vlan.c:110) rtnl_dellink (net/core/rtnetlink.c:3511 net/core/rtnetlink.c:3553) rtnetlink_rcv_msg (net/core/rtnetlink.c:6945) netlink_rcv_skb (net/netlink/af_netlink.c:2535) netlink_unicast (net/netlink/af_netlink.c:1314 net/netlink/af_netlink.c:133= 9) netlink_sendmsg (net/netlink/af_netlink.c:1883) ____sys_sendmsg (net/socket.c:712 net/socket.c:727 net/socket.c:2566) [2] kernel BUG at net/8021q/vlan.c:99! Oops: invalid opcode: 0000 [#1] SMP KASAN PTI CPU: 0 UID: 0 PID: 382 Comm: ip Not tainted 6.16.0-rc3 #61 PREEMPT(voluntar= y) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 RIP: 0010:unregister_vlan_dev (net/8021q/vlan.c:99 (discriminator 1)) RSP: 0018:ffff88810badf310 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff88810da84000 RCX: ffffffffb47ceb9a RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffff88810e8b43c8 RBP: 0000000000000000 R08: 0000000000000000 R09: fffffbfff6cefe80 R10: ffffffffb677f407 R11: ffff88810badf3c0 R12: ffff88810e8b4000 R13: 0000000000000000 R14: ffff88810642a5c0 R15: 000000000000017e FS: 00007f1ff68c20c0(0000) GS:ffff888163a24000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f1ff5dad240 CR3: 0000000107e56000 CR4: 00000000000006f0 Call Trace: rtnl_dellink (net/core/rtnetlink.c:3511 net/core/rtnetlink.c:3553) rtnetlink_rcv_msg (net/core/rtnetlink.c:6945) netlink_rcv_skb (net/netlink/af_netlink.c:2535) netlink_unicast (net/netlink/af_netlink.c:1314 net/netlink/af_netlink.c:133= 9) netlink_sendmsg (net/netlink/af_netlink.c:1883) ____sys_sendmsg (net/socket.c:712 net/socket.c:727 net/socket.c:2566) ___sys_sendmsg (net/socket.c:2622) __sys_sendmsg (net/socket.c:2652) do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:9= 4) Root cause is as below: step1: add vlan0 for real_dev, such as bond, team. register_vlan_dev vlan_vid_add(real_dev,htons(ETH_P_8021Q),0) //refcnt=3D1 step2: disable vlan filter feature and enable real_dev step3: change filter from 0 to 1 vlan_device_event vlan_filter_push_vids ndo_vlan_rx_add_vid //No refcnt added to real_dev vlan0 step4: real_dev down vlan_device_event vlan_vid_del(dev, htons(ETH_P_8021Q), 0); //refcnt=3D0 vlan_info_rcu_free //free vlan0 step5: real_dev up vlan_device_event vlan_vid_add(dev, htons(ETH_P_8021Q), 0); vlan_info_alloc //alloc new empty vid0. refcnt=3D1 step6: delete vlan0 unregister_vlan_dev BUG_ON(!vlan_info); //will trigger it if step5 was not executed vlan_group_set_device array =3D vg->vlan_devices_arrays //null-ptr-ref will be triggered after step5 E.g. the following sequence can reproduce null-ptr-ref $ ip link add bond0 type bond mode 0 $ ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q $ ethtool -K bond0 rx-vlan-filter off $ ifconfig bond0 up $ ethtool -K bond0 rx-vlan-filter on $ ifconfig bond0 down $ ifconfig bond0 up $ ip link del vlan0 Add the auto_vid0 flag to track the refcount of vlan0, and use this flag to determine whether to dec refcount while disabling real_dev. Fixes: ad1afb003939 ("vlan_dev: VLAN 0 should be treated as "no vlan tag" (= 802.1p packet)") Reported-by: syzbot+a8b046e462915c65b10b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=3Da8b046e462915c65b10b Co-developed-by: Ido Schimmel Signed-off-by: Ido Schimmel Signed-off-by: Dong Chenchen --- net/8021q/vlan.c | 42 +++++++++++++++++++++++++++++++++--------- net/8021q/vlan.h | 1 + 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 06908e37c3d9..9a6df8c1daf9 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -357,6 +357,35 @@ static int __vlan_device_event(struct net_device *dev,= unsigned long event) return err; } =20 +static void vlan_vid0_add(struct net_device *dev) +{ + struct vlan_info *vlan_info; + int err; + + if (!(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) + return; + + pr_info("adding VLAN 0 to HW filter on device %s\n", dev->name); + + err =3D vlan_vid_add(dev, htons(ETH_P_8021Q), 0); + if (err) + return; + + vlan_info =3D rtnl_dereference(dev->vlan_info); + vlan_info->auto_vid0 =3D true; +} + +static void vlan_vid0_del(struct net_device *dev) +{ + struct vlan_info *vlan_info =3D rtnl_dereference(dev->vlan_info); + + if (!vlan_info || !vlan_info->auto_vid0) + return; + + vlan_info->auto_vid0 =3D false; + vlan_vid_del(dev, htons(ETH_P_8021Q), 0); +} + static int vlan_device_event(struct notifier_block *unused, unsigned long = event, void *ptr) { @@ -378,15 +407,10 @@ static int vlan_device_event(struct notifier_block *u= nused, unsigned long event, return notifier_from_errno(err); } =20 - if ((event =3D=3D NETDEV_UP) && - (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) { - pr_info("adding VLAN 0 to HW filter on device %s\n", - dev->name); - vlan_vid_add(dev, htons(ETH_P_8021Q), 0); - } - if (event =3D=3D NETDEV_DOWN && - (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) - vlan_vid_del(dev, htons(ETH_P_8021Q), 0); + if (event =3D=3D NETDEV_UP) + vlan_vid0_add(dev); + else if (event =3D=3D NETDEV_DOWN) + vlan_vid0_del(dev); =20 vlan_info =3D rtnl_dereference(dev->vlan_info); if (!vlan_info) diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 5eaf38875554..c7ffe591d593 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -33,6 +33,7 @@ struct vlan_info { struct vlan_group grp; struct list_head vid_list; unsigned int nr_vids; + bool auto_vid0; struct rcu_head rcu; }; =20 --=20 2.25.1 From nobody Wed Oct 8 02:00:44 2025 Received: from szxga03-in.huawei.com (szxga03-in.huawei.com [45.249.212.189]) (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 7683229B777; Thu, 3 Jul 2025 07:54:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751529267; cv=none; b=TLsvaADLgy1t1lmDoKuPpR7FszlVp8HKCCAy3xqJDaApsiEGHC1mOlE8F1R53bx8oZ3FJCBT6yRFZJsD0/q18Yx0VoJML9xSGWpXiW2VMTPITyDd+aUK7v2vyUk1+M1B0t7ks33WqYhrSU0URTt1XFMo2SfL0Dq8in0ngfXv/wA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751529267; c=relaxed/simple; bh=wFwlRHQBXlbvkr8JtQ9aPLQFmhdSqrS1iHXAl9Wv9+A=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PmGAWW2ldxOXmTc3OWX0qs/zWPW9891wwywHknDSJaKTye59oV1rU2SLMwmmhWqjySMlqNjhwk+rlcak4Qt3CuhAZDAcVCvkar9qz/TkAVEgoZHxmgiKN2gCkeVG2DsIjg3G4pV0WbO8r/P099en49pfUCIEVMT9nnyrrfKgQOU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.162.254]) by szxga03-in.huawei.com (SkyGuard) with ESMTP id 4bXppP5xZnz1GCFS; Thu, 3 Jul 2025 15:50:21 +0800 (CST) Received: from dggemv705-chm.china.huawei.com (unknown [10.3.19.32]) by mail.maildlp.com (Postfix) with ESMTPS id 317EF180105; Thu, 3 Jul 2025 15:54:23 +0800 (CST) Received: from kwepemq200002.china.huawei.com (7.202.195.90) by dggemv705-chm.china.huawei.com (10.3.19.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Thu, 3 Jul 2025 15:54:22 +0800 Received: from localhost.localdomain (10.175.104.82) by kwepemq200002.china.huawei.com (7.202.195.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Thu, 3 Jul 2025 15:54:22 +0800 From: Dong Chenchen To: , , , , , , , , , CC: , , Subject: [PATCH net v2 2/2] selftests: Add test cases for vlan_filter modification during runtime Date: Thu, 3 Jul 2025 15:57:02 +0800 Message-ID: <20250703075702.1063149-3-dongchenchen2@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250703075702.1063149-1-dongchenchen2@huawei.com> References: <20250703075702.1063149-1-dongchenchen2@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems200001.china.huawei.com (7.221.188.67) To kwepemq200002.china.huawei.com (7.202.195.90) Content-Type: text/plain; charset="utf-8" Add test cases for vlan_filter modification during runtime, which may triger null-ptr-ref or memory leak of vlan0. Signed-off-by: Dong Chenchen --- tools/testing/selftests/net/vlan_hw_filter.sh | 98 ++++++++++++++++--- 1 file changed, 86 insertions(+), 12 deletions(-) diff --git a/tools/testing/selftests/net/vlan_hw_filter.sh b/tools/testing/= selftests/net/vlan_hw_filter.sh index 7bc804ffaf7c..0fb56baf28e4 100755 --- a/tools/testing/selftests/net/vlan_hw_filter.sh +++ b/tools/testing/selftests/net/vlan_hw_filter.sh @@ -3,27 +3,101 @@ =20 readonly NETNS=3D"ns-$(mktemp -u XXXXXX)" =20 +ALL_TESTS=3D" + test_vlan_filter_check + test_vlan0_del_crash_01 + test_vlan0_del_crash_02 + test_vlan0_del_crash_03 + test_vid0_memleak +" + ret=3D0 =20 +setup() { + ip netns add ${NETNS} +} + cleanup() { - ip netns del $NETNS + ip netns del $NETNS 2>/dev/null } =20 trap cleanup EXIT =20 fail() { - echo "ERROR: ${1:-unexpected return code} (ret: $_)" >&2 - ret=3D1 + echo "ERROR: ${1:-unexpected return code} (ret: $_)" >&2 + ret=3D1 +} + +tests_run() +{ + local current_test + for current_test in ${TESTS:-$ALL_TESTS}; do + $current_test + done +} + +test_vlan_filter_check() { + setup + ip netns exec ${NETNS} ip link add bond0 type bond mode 0 + ip netns exec ${NETNS} ip link add bond_slave_1 type veth peer veth2 + ip netns exec ${NETNS} ip link set bond_slave_1 master bond0 + ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off + ip netns exec ${NETNS} ip link add link bond_slave_1 name bond_slave_1.0 = type vlan id 0 + ip netns exec ${NETNS} ip link add link bond0 name bond0.0 type vlan id 0 + ip netns exec ${NETNS} ip link set bond_slave_1 nomaster + ip netns exec ${NETNS} ip link del veth2 || fail "Please check vlan HW fi= lter function" + cleanup } =20 -ip netns add ${NETNS} -ip netns exec ${NETNS} ip link add bond0 type bond mode 0 -ip netns exec ${NETNS} ip link add bond_slave_1 type veth peer veth2 -ip netns exec ${NETNS} ip link set bond_slave_1 master bond0 -ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off -ip netns exec ${NETNS} ip link add link bond_slave_1 name bond_slave_1.0 t= ype vlan id 0 -ip netns exec ${NETNS} ip link add link bond0 name bond0.0 type vlan id 0 -ip netns exec ${NETNS} ip link set bond_slave_1 nomaster -ip netns exec ${NETNS} ip link del veth2 || fail "Please check vlan HW fil= ter function" +#enable vlan_filter feature of real_dev with vlan0 during running time +test_vlan0_del_crash_01() { + setup + ip netns exec ${NETNS} ip link add bond0 type bond mode 0 + ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 p= rotocol 802.1q + ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off + ip netns exec ${NETNS} ifconfig bond0 up + ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on + ip netns exec ${NETNS} ifconfig bond0 down + ip netns exec ${NETNS} ifconfig bond0 up + ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW fi= lter function" + cleanup +} + +#enable vlan_filter feature and add vlan0 for real_dev during running time +test_vlan0_del_crash_02() { + setup + ip netns exec ${NETNS} ip link add bond0 type bond mode 0 + ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off + ip netns exec ${NETNS} ifconfig bond0 up + ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on + ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 p= rotocol 802.1q + ip netns exec ${NETNS} ifconfig bond0 down + ip netns exec ${NETNS} ifconfig bond0 up + ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW fi= lter function" + cleanup +} + +#enable vlan_filter feature of real_dev during running time +#test kernel_bug of vlan unregister +test_vlan0_del_crash_03() { + setup + ip netns exec ${NETNS} ip link add bond0 type bond mode 0 + ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 p= rotocol 802.1q + ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off + ip netns exec ${NETNS} ifconfig bond0 up + ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on + ip netns exec ${NETNS} ifconfig bond0 down + ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW fi= lter function" + cleanup +} + +test_vid0_memleak() { + setup + ip netns exec ${NETNS} ip link add bond0 up type bond mode 0 + ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off + ip netns exec ${NETNS} ip link del dev bond0 || fail "Please check vlan H= W filter function" + cleanup +} =20 +tests_run exit $ret --=20 2.25.1