| From bippy-7c5fe7eed585 Mon Sep 17 00:00:00 2001 |
| From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| To: <linux-cve-announce@vger.kernel.org> |
| Reply-to: <cve@kernel.org>, <linux-kernel@vger.kernel.org> |
| Subject: CVE-2025-21986: net: switchdev: Convert blocking notification chain to a raw one |
| |
| Description |
| =========== |
| |
| In the Linux kernel, the following vulnerability has been resolved: |
| |
| net: switchdev: Convert blocking notification chain to a raw one |
| |
| A blocking notification chain uses a read-write semaphore to protect the |
| integrity of the chain. The semaphore is acquired for writing when |
| adding / removing notifiers to / from the chain and acquired for reading |
| when traversing the chain and informing notifiers about an event. |
| |
| In case of the blocking switchdev notification chain, recursive |
| notifications are possible which leads to the semaphore being acquired |
| twice for reading and to lockdep warnings being generated [1]. |
| |
| Specifically, this can happen when the bridge driver processes a |
| SWITCHDEV_BRPORT_UNOFFLOADED event which causes it to emit notifications |
| about deferred events when calling switchdev_deferred_process(). |
| |
| Fix this by converting the notification chain to a raw notification |
| chain in a similar fashion to the netdev notification chain. Protect |
| the chain using the RTNL mutex by acquiring it when modifying the chain. |
| Events are always informed under the RTNL mutex, but add an assertion in |
| call_switchdev_blocking_notifiers() to make sure this is not violated in |
| the future. |
| |
| Maintain the "blocking" prefix as events are always emitted from process |
| context and listeners are allowed to block. |
| |
| [1]: |
| WARNING: possible recursive locking detected |
| 6.14.0-rc4-custom-g079270089484 #1 Not tainted |
| -------------------------------------------- |
| ip/52731 is trying to acquire lock: |
| ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0 |
| |
| but task is already holding lock: |
| ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0 |
| |
| other info that might help us debug this: |
| Possible unsafe locking scenario: |
| CPU0 |
| ---- |
| lock((switchdev_blocking_notif_chain).rwsem); |
| lock((switchdev_blocking_notif_chain).rwsem); |
| |
| *** DEADLOCK *** |
| May be due to missing lock nesting notation |
| 3 locks held by ip/52731: |
| #0: ffffffff84f795b0 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x727/0x1dc0 |
| #1: ffffffff8731f628 (&net->rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x790/0x1dc0 |
| #2: ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0 |
| |
| stack backtrace: |
| ... |
| ? __pfx_down_read+0x10/0x10 |
| ? __pfx_mark_lock+0x10/0x10 |
| ? __pfx_switchdev_port_attr_set_deferred+0x10/0x10 |
| blocking_notifier_call_chain+0x58/0xa0 |
| switchdev_port_attr_notify.constprop.0+0xb3/0x1b0 |
| ? __pfx_switchdev_port_attr_notify.constprop.0+0x10/0x10 |
| ? mark_held_locks+0x94/0xe0 |
| ? switchdev_deferred_process+0x11a/0x340 |
| switchdev_port_attr_set_deferred+0x27/0xd0 |
| switchdev_deferred_process+0x164/0x340 |
| br_switchdev_port_unoffload+0xc8/0x100 [bridge] |
| br_switchdev_blocking_event+0x29f/0x580 [bridge] |
| notifier_call_chain+0xa2/0x440 |
| blocking_notifier_call_chain+0x6e/0xa0 |
| switchdev_bridge_port_unoffload+0xde/0x1a0 |
| ... |
| |
| The Linux kernel CVE team has assigned CVE-2025-21986 to this issue. |
| |
| |
| Affected and fixed versions |
| =========================== |
| |
| Issue introduced in 6.1.80 with commit 91ac2c79e896b28a4a3a262384689ee6dfeaf083 and fixed in 6.1.132 with commit af757f5ee3f754c5dceefb05c12ff37cb46fc682 |
| Issue introduced in 6.6.19 with commit a83856bd0c240267a86ce3388f3437d6ba5ac5ca and fixed in 6.6.84 with commit 1f7d051814e7a0cb1f0717ed5527c1059992129d |
| Issue introduced in 6.8 with commit f7a70d650b0b6b0134ccba763d672c8439d9f09b and fixed in 6.12.20 with commit a597d4b75669ec82c72cbee9fe75a15d04b35b2b |
| Issue introduced in 6.8 with commit f7a70d650b0b6b0134ccba763d672c8439d9f09b and fixed in 6.13.8 with commit f9ed3fb50b872bd78bcb01f25087f9e4e25085d8 |
| Issue introduced in 6.8 with commit f7a70d650b0b6b0134ccba763d672c8439d9f09b and fixed in 6.14 with commit 62531a1effa87bdab12d5104015af72e60d926ff |
| Issue introduced in 6.7.7 with commit a7589eca09929c3cc2a62950ef7f40bcc58afe3a |
| |
| Please see https://www.kernel.org for a full list of currently supported |
| kernel versions by the kernel community. |
| |
| Unaffected versions might change over time as fixes are backported to |
| older supported kernel versions. The official CVE entry at |
| https://cve.org/CVERecord/?id=CVE-2025-21986 |
| will be updated if fixes are backported, please check that for the most |
| up to date information about this issue. |
| |
| |
| Affected files |
| ============== |
| |
| The file(s) affected by this issue are: |
| net/switchdev/switchdev.c |
| |
| |
| Mitigation |
| ========== |
| |
| The Linux kernel CVE team recommends that you update to the latest |
| stable kernel version for this, and many other bugfixes. Individual |
| changes are never tested alone, but rather are part of a larger kernel |
| release. Cherry-picking individual commits is not recommended or |
| supported by the Linux kernel community at all. If however, updating to |
| the latest release is impossible, the individual changes to resolve this |
| issue can be found at these commits: |
| https://git.kernel.org/stable/c/af757f5ee3f754c5dceefb05c12ff37cb46fc682 |
| https://git.kernel.org/stable/c/1f7d051814e7a0cb1f0717ed5527c1059992129d |
| https://git.kernel.org/stable/c/a597d4b75669ec82c72cbee9fe75a15d04b35b2b |
| https://git.kernel.org/stable/c/f9ed3fb50b872bd78bcb01f25087f9e4e25085d8 |
| https://git.kernel.org/stable/c/62531a1effa87bdab12d5104015af72e60d926ff |