diff mbox series

[net] net: bridge: mst: fix vlan use-after-free

Message ID 20240513110627.770389-1-razor@blackwall.org (mailing list archive)
State Accepted
Commit 3a7c1661ae1383364cd6092d851f5e5da64d476b
Delegated to: Netdev Maintainers
Headers show
Series [net] net: bridge: mst: fix vlan use-after-free | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 925 this patch: 925
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 8 of 8 maintainers
netdev/build_clang success Errors and warnings before: 936 this patch: 936
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 936 this patch: 936
netdev/checkpatch warning WARNING: Possible repeated word: 'Google'
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-05-14--00-00 (tests: 1022)

Commit Message

Nikolay Aleksandrov May 13, 2024, 11:06 a.m. UTC
syzbot reported a suspicious rcu usage[1] in bridge's mst code. While
fixing it I noticed that nothing prevents a vlan to be freed while
walking the list from the same path (br forward delay timer). Fix the rcu
usage and also make sure we are not accessing freed memory by making
br_mst_vlan_set_state use rcu read lock.

[1]
 WARNING: suspicious RCU usage
 6.9.0-rc6-syzkaller #0 Not tainted
 -----------------------------
 net/bridge/br_private.h:1599 suspicious rcu_dereference_protected() usage!
 ...
 stack backtrace:
 CPU: 1 PID: 8017 Comm: syz-executor.1 Not tainted 6.9.0-rc6-syzkaller #0
 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024
 Call Trace:
  <IRQ>
  __dump_stack lib/dump_stack.c:88 [inline]
  dump_stack_lvl+0x241/0x360 lib/dump_stack.c:114
  lockdep_rcu_suspicious+0x221/0x340 kernel/locking/lockdep.c:6712
  nbp_vlan_group net/bridge/br_private.h:1599 [inline]
  br_mst_set_state+0x1ea/0x650 net/bridge/br_mst.c:105
  br_set_state+0x28a/0x7b0 net/bridge/br_stp.c:47
  br_forward_delay_timer_expired+0x176/0x440 net/bridge/br_stp_timer.c:88
  call_timer_fn+0x18e/0x650 kernel/time/timer.c:1793
  expire_timers kernel/time/timer.c:1844 [inline]
  __run_timers kernel/time/timer.c:2418 [inline]
  __run_timer_base+0x66a/0x8e0 kernel/time/timer.c:2429
  run_timer_base kernel/time/timer.c:2438 [inline]
  run_timer_softirq+0xb7/0x170 kernel/time/timer.c:2448
  __do_softirq+0x2c6/0x980 kernel/softirq.c:554
  invoke_softirq kernel/softirq.c:428 [inline]
  __irq_exit_rcu+0xf2/0x1c0 kernel/softirq.c:633
  irq_exit_rcu+0x9/0x30 kernel/softirq.c:645
  instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1043 [inline]
  sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1043
  </IRQ>
  <TASK>
 asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:702
 RIP: 0010:lock_acquire+0x264/0x550 kernel/locking/lockdep.c:5758
 Code: 2b 00 74 08 4c 89 f7 e8 ba d1 84 00 f6 44 24 61 02 0f 85 85 01 00 00 41 f7 c7 00 02 00 00 74 01 fb 48 c7 44 24 40 0e 36 e0 45 <4b> c7 44 25 00 00 00 00 00 43 c7 44 25 09 00 00 00 00 43 c7 44 25
 RSP: 0018:ffffc90013657100 EFLAGS: 00000206
 RAX: 0000000000000001 RBX: 1ffff920026cae2c RCX: 0000000000000001
 RDX: dffffc0000000000 RSI: ffffffff8bcaca00 RDI: ffffffff8c1eaa60
 RBP: ffffc90013657260 R08: ffffffff92efe507 R09: 1ffffffff25dfca0
 R10: dffffc0000000000 R11: fffffbfff25dfca1 R12: 1ffff920026cae28
 R13: dffffc0000000000 R14: ffffc90013657160 R15: 0000000000000246

Fixes: ec7328b59176 ("net: bridge: mst: Multiple Spanning Tree (MST) mode")
Reported-by: syzbot+fa04eb8a56fd923fc5d8@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=fa04eb8a56fd923fc5d8
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
 net/bridge/br_mst.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

Comments

Simon Horman May 14, 2024, 10:04 a.m. UTC | #1
On Mon, May 13, 2024 at 02:06:27PM +0300, Nikolay Aleksandrov wrote:
> syzbot reported a suspicious rcu usage[1] in bridge's mst code. While
> fixing it I noticed that nothing prevents a vlan to be freed while
> walking the list from the same path (br forward delay timer). Fix the rcu
> usage and also make sure we are not accessing freed memory by making
> br_mst_vlan_set_state use rcu read lock.
> 
> [1]
>  WARNING: suspicious RCU usage
>  6.9.0-rc6-syzkaller #0 Not tainted
>  -----------------------------
>  net/bridge/br_private.h:1599 suspicious rcu_dereference_protected() usage!
>  ...
>  stack backtrace:
>  CPU: 1 PID: 8017 Comm: syz-executor.1 Not tainted 6.9.0-rc6-syzkaller #0
>  Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024
>  Call Trace:
>   <IRQ>
>   __dump_stack lib/dump_stack.c:88 [inline]
>   dump_stack_lvl+0x241/0x360 lib/dump_stack.c:114
>   lockdep_rcu_suspicious+0x221/0x340 kernel/locking/lockdep.c:6712
>   nbp_vlan_group net/bridge/br_private.h:1599 [inline]
>   br_mst_set_state+0x1ea/0x650 net/bridge/br_mst.c:105
>   br_set_state+0x28a/0x7b0 net/bridge/br_stp.c:47
>   br_forward_delay_timer_expired+0x176/0x440 net/bridge/br_stp_timer.c:88
>   call_timer_fn+0x18e/0x650 kernel/time/timer.c:1793
>   expire_timers kernel/time/timer.c:1844 [inline]
>   __run_timers kernel/time/timer.c:2418 [inline]
>   __run_timer_base+0x66a/0x8e0 kernel/time/timer.c:2429
>   run_timer_base kernel/time/timer.c:2438 [inline]
>   run_timer_softirq+0xb7/0x170 kernel/time/timer.c:2448
>   __do_softirq+0x2c6/0x980 kernel/softirq.c:554
>   invoke_softirq kernel/softirq.c:428 [inline]
>   __irq_exit_rcu+0xf2/0x1c0 kernel/softirq.c:633
>   irq_exit_rcu+0x9/0x30 kernel/softirq.c:645
>   instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1043 [inline]
>   sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1043
>   </IRQ>
>   <TASK>
>  asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:702
>  RIP: 0010:lock_acquire+0x264/0x550 kernel/locking/lockdep.c:5758
>  Code: 2b 00 74 08 4c 89 f7 e8 ba d1 84 00 f6 44 24 61 02 0f 85 85 01 00 00 41 f7 c7 00 02 00 00 74 01 fb 48 c7 44 24 40 0e 36 e0 45 <4b> c7 44 25 00 00 00 00 00 43 c7 44 25 09 00 00 00 00 43 c7 44 25
>  RSP: 0018:ffffc90013657100 EFLAGS: 00000206
>  RAX: 0000000000000001 RBX: 1ffff920026cae2c RCX: 0000000000000001
>  RDX: dffffc0000000000 RSI: ffffffff8bcaca00 RDI: ffffffff8c1eaa60
>  RBP: ffffc90013657260 R08: ffffffff92efe507 R09: 1ffffffff25dfca0
>  R10: dffffc0000000000 R11: fffffbfff25dfca1 R12: 1ffff920026cae28
>  R13: dffffc0000000000 R14: ffffc90013657160 R15: 0000000000000246
> 
> Fixes: ec7328b59176 ("net: bridge: mst: Multiple Spanning Tree (MST) mode")
> Reported-by: syzbot+fa04eb8a56fd923fc5d8@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=fa04eb8a56fd923fc5d8
> Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>

Reviewed-by: Simon Horman <horms@kernel.org>
patchwork-bot+netdevbpf@kernel.org May 15, 2024, 10:50 a.m. UTC | #2
Hello:

This patch was applied to netdev/net.git (main)
by David S. Miller <davem@davemloft.net>:

On Mon, 13 May 2024 14:06:27 +0300 you wrote:
> syzbot reported a suspicious rcu usage[1] in bridge's mst code. While
> fixing it I noticed that nothing prevents a vlan to be freed while
> walking the list from the same path (br forward delay timer). Fix the rcu
> usage and also make sure we are not accessing freed memory by making
> br_mst_vlan_set_state use rcu read lock.
> 
> [1]
>  WARNING: suspicious RCU usage
>  6.9.0-rc6-syzkaller #0 Not tainted
> 
> [...]

Here is the summary with links:
  - [net] net: bridge: mst: fix vlan use-after-free
    https://git.kernel.org/netdev/net/c/3a7c1661ae13

You are awesome, thank you!
diff mbox series

Patch

diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c
index ee680adcee17..3c66141d34d6 100644
--- a/net/bridge/br_mst.c
+++ b/net/bridge/br_mst.c
@@ -78,7 +78,7 @@  static void br_mst_vlan_set_state(struct net_bridge_port *p, struct net_bridge_v
 {
 	struct net_bridge_vlan_group *vg = nbp_vlan_group(p);
 
-	if (v->state == state)
+	if (br_vlan_get_state(v) == state)
 		return;
 
 	br_vlan_set_state(v, state);
@@ -100,11 +100,12 @@  int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
 	};
 	struct net_bridge_vlan_group *vg;
 	struct net_bridge_vlan *v;
-	int err;
+	int err = 0;
 
+	rcu_read_lock();
 	vg = nbp_vlan_group(p);
 	if (!vg)
-		return 0;
+		goto out;
 
 	/* MSTI 0 (CST) state changes are notified via the regular
 	 * SWITCHDEV_ATTR_ID_PORT_STP_STATE.
@@ -112,17 +113,20 @@  int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
 	if (msti) {
 		err = switchdev_port_attr_set(p->dev, &attr, extack);
 		if (err && err != -EOPNOTSUPP)
-			return err;
+			goto out;
 	}
 
-	list_for_each_entry(v, &vg->vlan_list, vlist) {
+	err = 0;
+	list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
 		if (v->brvlan->msti != msti)
 			continue;
 
 		br_mst_vlan_set_state(p, v, state);
 	}
 
-	return 0;
+out:
+	rcu_read_unlock();
+	return err;
 }
 
 static void br_mst_vlan_sync_state(struct net_bridge_vlan *pv, u16 msti)