git: afaf984ae0dc - stable/15 - ipfilter: Interface name must not extend beyond end of buffer

From: Cy Schubert <cy_at_FreeBSD.org>
Date: Fri, 20 Feb 2026 02:23:58 UTC
The branch stable/15 has been updated by cy:

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

commit afaf984ae0dc65fce9df561d6d3543addf53adde
Author:     Cy Schubert <cy@FreeBSD.org>
AuthorDate: 2026-01-08 17:41:53 +0000
Commit:     Cy Schubert <cy@FreeBSD.org>
CommitDate: 2026-02-20 02:23:44 +0000

    ipfilter: Interface name must not extend beyond end of buffer
    
    sifpidx (an interface name) cannot extend beyond the end of the
    fr_names buffer.
    
    We do the validation for fr_sifpidx here because it is a union that
    contains an offset only when fr_sifpidx points to an interface name,
    an offset into fr_names. The union is  an offset into fr_names in this
    case only.
    
    interr_tbl now becomes a static variable outside a function to facilitate
    its use by two functions within fil.c
    
    Note that sifpidx is only used in ipf_sync() which implments ipf -y.
    
    Reported by:    Ilja Van Sprundel <ivansprundel@ioactive.com>
    MFC after:      1 week
    
    (cherry picked from commit 47fb51847fdea3f1cce841b5f2bbbcd6f8a04ee0)
---
 sys/netpfil/ipfilter/netinet/fil.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/sys/netpfil/ipfilter/netinet/fil.c b/sys/netpfil/ipfilter/netinet/fil.c
index 355c633d59d8..09640623fdf2 100644
--- a/sys/netpfil/ipfilter/netinet/fil.c
+++ b/sys/netpfil/ipfilter/netinet/fil.c
@@ -236,6 +236,11 @@ static const	struct	optlist	secopt[] = {
 	{ IPSO_CLASS_RES1,	0x80 }
 };
 
+/*
+ * Internal errors set by ipf_check_names_string().
+ */
+static const int interr_tbl[3] = { 152, 156, 153 };
+
 char	ipfilter_version[] = IPL_VERSION;
 
 int	ipf_features = 0
@@ -3906,7 +3911,7 @@ ipf_synclist(ipf_main_softc_t *softc, frentry_t *fr, void *ifp)
 	frentry_t *frt, *start = fr;
 	frdest_t *fdp;
 	char *name;
-	int error;
+	int error, interr;
 	void *ifa;
 	int v, i;
 
@@ -3933,6 +3938,21 @@ ipf_synclist(ipf_main_softc_t *softc, frentry_t *fr, void *ifp)
 		}
 
 		if ((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) {
+			/*
+			 * We do the validation for fr_sifpidx here because
+			 * it is a union that contains an offset only when
+			 * fr_sifpidx points to an interface name, an offset
+			 * into fr_names. The union is  an offset into
+			 * fr_names in this case only.
+			 *
+			 * Note that sifpidx is only used in ipf_sync() which
+			 * implments ipf -y.
+			 */
+			if ((interr = ipf_check_names_string(fr->fr_names, fr->fr_namelen, fr->fr_sifpidx)) != 0) {
+				IPFERROR(interr_tbl[interr-1]);
+				error = EINVAL;
+				goto unwind;
+			}
 			if (fr->fr_satype != FRI_NORMAL &&
 			    fr->fr_satype != FRI_LOOKUP) {
 				ifa = ipf_resolvenic(softc, fr->fr_names +
@@ -4404,7 +4424,6 @@ frrequest(ipf_main_softc_t *softc, int unit, ioctlcmd_t req, caddr_t data,
 	int set, int makecopy)
 {
 	int error = 0, in, family, need_free = 0, interr, i;
-	int interr_tbl[3] = { 152, 156, 153};
 	enum {	OP_ADD,		/* add rule */
 		OP_REM,		/* remove rule */
 		OP_ZERO 	/* zero statistics and counters */ }