⬢ DragonFlyBSD Kernel Audit
DF-3280 / fix.diff
← back to finding ↓ download raw
--- if.c.orig	2026-09-10 02:34:29.419130783 +0000
+++ if.c.fixed	2026-09-10 02:35:58.185986949 +0000
@@ -1348,6 +1379,36 @@
 		return (ENOMEM);
 
 	ifgroup_lockmgr(LK_SHARED);
+
+	/*
+	 * The group may have been destroyed (or destroyed and
+	 * recreated) while we were not holding the lock.  Look it up
+	 * again rather than dereferencing the potentially stale
+	 * pointer found above.
+	 */
+	TAILQ_FOREACH(ifg, &ifg_head, ifg_next) {
+		if (strcmp(ifg->ifg_group, ifgr->ifgr_name) == 0)
+			break;
+	}
+	if (ifg == NULL) {
+		ifgroup_lockmgr(LK_RELEASE);
+		kfree(ifgrq, M_TEMP);
+		return (ENOENT);
+	}
+
+	/*
+	 * Membership may also have changed; recompute the length and
+	 * re-check it against the caller's buffer.
+	 */
+	len = 0;
+	TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
+		len += sizeof(struct ifg_req);
+	if (ifgr->ifgr_len != len) {
+		ifgroup_lockmgr(LK_RELEASE);
+		kfree(ifgrq, M_TEMP);
+		return (EINVAL);
+	}
+
 	p = ifgrq;
 	TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) {
 		if (len < sizeof(struct ifg_req)) {