git: 9835aa0d7dea - stable/12 - if_bridge: fix potential panic

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Sun, 09 Jul 2023 15:25:17 UTC
The branch stable/12 has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=9835aa0d7dea7776165c770d059de4d9ead86dd1

commit 9835aa0d7dea7776165c770d059de4d9ead86dd1
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-05-18 18:04:45 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-07-09 12:27:01 +0000

    if_bridge: fix potential panic
    
    When a new bridge_rtnode is added it is added with a NULL brt_dst. The
    brt_dst is set after the entry is added. This means there's a small
    window where another core could also attempt to add this node, leading
    to the code attempting to log that the MAC addresses moved to a new
    interface.
    Aside from that being a spurious log entry it also panics, because
    obif is NULL (and we attempt to dereference it).
    
    Avoid this by settings brt_dst before we insert the bridge_rtnode.
    Assert that obif is non-NULL, as an extra precaution.
    
    Reported by:    olivier@
    Reviewed by:    zlei@
    Differential Revision:  https://reviews.freebsd.org/D40147
    
    (cherry picked from commit f3546eacf0daac55fe08b6ad5849b0e440f75ffb)
---
 sys/net/if_bridge.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 28e8e8856b8e..23c1c4171761 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -2882,12 +2882,12 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, uint16_t vlan,
 		memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
 		brt->brt_vlan = vlan;
 
+		brt->brt_dst = bif;
 		if ((error = bridge_rtnode_insert(sc, brt)) != 0) {
 			uma_zfree(V_bridge_rtnode_zone, brt);
 			BRIDGE_RT_UNLOCK(sc);
 			return (error);
 		}
-		brt->brt_dst = bif;
 		bif->bif_addrcnt++;
 
 		BRIDGE_RT_UNLOCK(sc);
@@ -2895,6 +2895,8 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, uint16_t vlan,
 
 	if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
 	    (obif = brt->brt_dst) != bif) {
+		MPASS(obif != NULL);
+
 		BRIDGE_RT_LOCK(sc);
 		brt->brt_dst->bif_addrcnt--;
 		brt->brt_dst = bif;