git: 5614daf09f71 - stable/15 - ifnet: Restore previous size of if_afdata

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Sun, 16 Aug 2026 20:25:20 UTC
The branch stable/15 has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=5614daf09f71232b1118d2687228d5dc2b9ce520

commit 5614daf09f71232b1118d2687228d5dc2b9ce520
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-08-14 08:23:47 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-08-16 20:24:58 +0000

    ifnet: Restore previous size of if_afdata
    
    Struct ifnet contains an array if_afdata of AF_MAX pointers to address
    information for each possible address family.  Since 2013, when AF_MAX
    was inadvertently changed to be equal to the highest possible value,
    instead of one more than the highest possible value, this array has been
    too small in theory, but this never mattered in practice because the
    higher address families were not assignable to interfaces.
    
    My recent commit which corrected the value of AF_MAX had the side effect
    of breaking the KBI by changing the size and layout of struct ifnet.
    This manifested itself as kernel panics when using third-party network
    drivers and went unnoticed in main because if_afdata no longer exists
    there.  Address the issue for stable/15 and stable/14 by keeping the
    correct value of AF_MAX but deliberately making if_afdata off by one,
    restoring its previous size.
    
    Fixes:          ddd850aa7720 ("sys/socket.h: Fix AF_MAX")
    Sponsored by:   Klara, Inc.
    Sponsored by:   NetApp, Inc.
    Reviewed by:    glebius
    Differential Revision:  https://reviews.freebsd.org/D58840
---
 sys/net/if.c         | 2 +-
 sys/net/if_private.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/net/if.c b/sys/net/if.c
index 8ee7d3f3f924..a38998b5c02e 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1119,7 +1119,7 @@ if_detach_internal(struct ifnet *ifp, bool vmove)
 	struct ifaddr *ifa;
 	int i;
 	struct domain *dp;
-	void *if_afdata[AF_MAX];
+	void *if_afdata[nitems(ifp->if_afdata)];
 #ifdef VIMAGE
 	bool shutdown;
 
diff --git a/sys/net/if_private.h b/sys/net/if_private.h
index a5cc09127f6f..76e4cdbf40c2 100644
--- a/sys/net/if_private.h
+++ b/sys/net/if_private.h
@@ -101,7 +101,7 @@ struct ifnet {
 	void	*if_hw_addr;		/* hardware link-level address */
 	const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
 	struct	mtx if_afdata_lock;
-	void	*if_afdata[AF_MAX];
+	void	*if_afdata[AF_MAX - 1];	/* off by one for historical reasons */
 	int	if_afdata_initialized;
 
 	/* Additional features hung off the interface. */