git: 24268f262b41 - stable/14 - sysctl: Make sysctl_ctx_free() a bit safer

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Sat, 11 May 2024 14:16:28 UTC
The branch stable/14 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=24268f262b41cd82ed492b4b0776214e549a56e7

commit 24268f262b41cd82ed492b4b0776214e549a56e7
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-05-01 11:57:56 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-05-11 14:15:21 +0000

    sysctl: Make sysctl_ctx_free() a bit safer
    
    Clear the list before returning so that sysctl_ctx_free() can be called
    more than once on the same list without side effects.  This simplifies
    error handling in drivers; previously, drivers would have to be careful
    to call sysctl_ctx_free() at most once to avoid a use-after-free.
    
    While here, use TAILQ_FOREACH_SAFE in the loop which unregisters OIDs.
    
    Reviewed by:    thj, emaste
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D45041
    
    (cherry picked from commit d5eae57088f5eec5df49fea8e8623521f596db68)
---
 sys/kern/kern_sysctl.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 814579a80f5a..53b61c08713f 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -634,17 +634,15 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist)
 		return(EBUSY);
 	}
 	/* Now really delete the entries */
-	e = TAILQ_FIRST(clist);
-	while (e != NULL) {
-		e1 = TAILQ_NEXT(e, link);
+	TAILQ_FOREACH_SAFE(e, clist, link, e1) {
 		error = sysctl_remove_oid_locked(e->entry, 1, 0);
 		if (error)
 			panic("sysctl_remove_oid: corrupt tree, entry: %s",
 			    e->entry->oid_name);
 		free(e, M_SYSCTLOID);
-		e = e1;
 	}
 	SYSCTL_WUNLOCK();
+	TAILQ_INIT(clist);
 	return (error);
 }