git: 4c63ecf5c77c - main - routing: fix panic triggered by the 'gr_idx != 0' assert in nhg code

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Wed, 17 May 2023 08:40:38 UTC
The branch main has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=4c63ecf5c77cdd023282c2ab585d139aa0408d42

commit 4c63ecf5c77cdd023282c2ab585d139aa0408d42
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2023-05-17 08:24:05 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-05-17 08:40:29 +0000

    routing: fix panic triggered by the 'gr_idx != 0' assert in nhg code
    
    Nexthop groups can be referenced by the external code. The reference
     can be released after the VNET destruction. Furthermore, nexthop
     groups use a single per-rib lock, which is destroyed during the
     VNET desctruction. To eliminate use-after-free problem, each nhg
     is marked as "unlinked" during the VNET destruction stage, leaving
     nhg_idx intact. Normally there should not be such nexthops, but if
     there are any, the kernel will panic on 'gr_idx != 0' when the
     last nhg reference is released.
    
    Address this by using the assert checks only when the nexthop group
     is destroyed during "valid" VNET lifetime.
    
    MFC after:      3 days
---
 sys/net/route/nhgrp_ctl.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/sys/net/route/nhgrp_ctl.c b/sys/net/route/nhgrp_ctl.c
index 2e9bcd4dc86f..ce5b154859f6 100644
--- a/sys/net/route/nhgrp_ctl.c
+++ b/sys/net/route/nhgrp_ctl.c
@@ -382,10 +382,11 @@ nhgrp_free(struct nhgrp_object *nhg)
 			NET_EPOCH_EXIT(et);
 			return;
 		}
+		MPASS((nhg_priv->nhg_idx == 0));
+		MPASS((nhg_priv->nhg_refcount == 0));
 	}
 	NET_EPOCH_EXIT(et);
 
-	KASSERT((nhg_priv->nhg_idx == 0), ("gr_idx != 0"));
 	NET_EPOCH_CALL(destroy_nhgrp_epoch, &nhg_priv->nhg_epoch_ctx);
 }
 
@@ -402,10 +403,6 @@ destroy_nhgrp_int(struct nhgrp_priv *nhg_priv)
 __noinline static void
 destroy_nhgrp(struct nhgrp_priv *nhg_priv)
 {
-
-	KASSERT((nhg_priv->nhg_refcount == 0), ("nhg_refcount != 0"));
-	KASSERT((nhg_priv->nhg_idx == 0), ("gr_idx != 0"));
-
 	IF_DEBUG_LEVEL(LOG_DEBUG2) {
 		char nhgbuf[NHOP_PRINT_BUFSIZE] __unused;
 		FIB_NH_LOG(LOG_DEBUG2, nhg_priv->nhg_nh_weights[0].nh,