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
This commit is contained in:
Mark Johnston 2024-05-01 07:57:56 -04:00
parent 4510f2ca91
commit d5eae57088

View file

@ -651,17 +651,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);
}