untrusted comment: verify with openbsd-79-base.pub
RWTSdNN9A3yvWLIRkDRolwRh/KdQEn5i0GKUNP6yuAUMCLZzG11uYTgpd09nCak6fkfeMa3MrOW81X1FBgYWuvHKHKlspAVCbQY=

OpenBSD 7.9 errata 007, July 16, 2026:

Stricter IPsec and IPComp input validation prevents kernel crash.

Apply by doing:
    signify -Vep /etc/signify/openbsd-79-base.pub -x 007_ipsec.patch.sig \
        -m - | (cd /usr/src && patch -p0)

And then rebuild and install a new kernel:
    KK=`sysctl -n kern.osversion | cut -d# -f1`
    cd /usr/src/sys/arch/`machine`/compile/$KK
    make obj
    make config
    make
    make install

Index: sys/crypto/cryptosoft.c
===================================================================
RCS file: /cvs/src/sys/crypto/cryptosoft.c,v
diff -u -p -r1.91 cryptosoft.c
--- sys/crypto/cryptosoft.c	24 Oct 2021 10:26:22 -0000	1.91
+++ sys/crypto/cryptosoft.c	13 Jul 2026 17:51:30 -0000
@@ -659,6 +659,7 @@ swcr_compdec(struct cryptodesc *crd, str
 	const struct comp_algo *cxf;
 	int adj;
 	u_int32_t result;
+	int error = 0;
 
 	cxf = sw->sw_cxf;
 
@@ -689,12 +690,23 @@ swcr_compdec(struct cryptodesc *crd, str
 	if (crd->crd_flags & CRD_F_COMP) {
 		if (result > crd->crd_len) {
 			/* Compression was useless, we lost time */
-			free(out, M_CRYPTO_DATA, result);
-			return 0;
+			goto out;
+		}
+	} else {
+		/* Decompressed IP packet must fit into mbuf cluster. */
+		if (outtype == CRYPTO_BUF_MBUF && result > MAXMCLBYTES) {
+			error = EMSGSIZE;
+			goto out;
 		}
 	}
 
-	COPYBACK(outtype, buf, crd->crd_skip, result, out);
+	if (outtype == CRYPTO_BUF_MBUF) {
+		error = m_copyback((struct mbuf *)buf, crd->crd_skip, result,
+		    out, M_NOWAIT);
+		if (error)
+			goto out;
+	} else
+		cuio_copyback((struct uio *)buf, crd->crd_skip, result, out);
 	if (result < crd->crd_len) {
 		adj = result - crd->crd_len;
 		if (outtype == CRYPTO_BUF_MBUF) {
@@ -720,8 +732,9 @@ swcr_compdec(struct cryptodesc *crd, str
 			}
 		}
 	}
+ out:
 	free(out, M_CRYPTO_DATA, result);
-	return 0;
+	return error;
 }
 
 /*
Index: sys/netinet/ip_ah.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ah.c,v
diff -u -p -r1.179 ip_ah.c
--- sys/netinet/ip_ah.c	11 Dec 2025 05:06:02 -0000	1.179
+++ sys/netinet/ip_ah.c	13 Jul 2026 17:51:30 -0000
@@ -545,6 +545,10 @@ ah_input(struct mbuf **mp, struct tdb *t
 	uint8_t calc[AH_ALEN_MAX];
 
 	rplen = AH_FLENGTH + sizeof(u_int32_t);
+	if (m->m_pkthdr.len < skip + rplen) {
+		ahstat_inc(ahs_hdrops);
+		goto drop;
+	}
 
 	/* Save the AH header, we use it throughout. */
 	m_copydata(m, skip + offsetof(struct ah, ah_hl), sizeof(u_int8_t), &hl);
Index: sys/netinet/ipsec_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ipsec_input.c,v
diff -u -p -r1.222 ipsec_input.c
--- sys/netinet/ipsec_input.c	11 Dec 2025 05:06:02 -0000	1.222
+++ sys/netinet/ipsec_input.c	13 Jul 2026 17:51:30 -0000
@@ -417,6 +417,10 @@ ipsec_common_input_cb(struct mbuf **mp, 
 			IPSEC_ISTAT(esps_hdrops, ahs_hdrops, ipcomps_hdrops);
 			goto baddone;
 		}
+		if (m->m_pkthdr.len > IP_MAXPACKET) {
+			IPSEC_ISTAT(esps_toobig, ahs_toobig, ipcomps_toobig);
+			goto baddone;
+		}
 
 		ip = mtod(m, struct ip *);
 		ip->ip_len = htons(m->m_pkthdr.len);
@@ -434,6 +438,10 @@ ipsec_common_input_cb(struct mbuf **mp, 
 			    ipsp_address(&tdbp->tdb_dst, buf, sizeof(buf)),
 			    ntohl(tdbp->tdb_spi));
 			IPSEC_ISTAT(esps_hdrops, ahs_hdrops, ipcomps_hdrops);
+			goto baddone;
+		}
+		if (m->m_pkthdr.len > IPV6_MAXPACKET + skip) {
+			IPSEC_ISTAT(esps_toobig, ahs_toobig, ipcomps_toobig);
 			goto baddone;
 		}
 
