untrusted comment: verify with openbsd-71-base.pub
RWR2eHwZTOEiTaVlOS0QOKp1zzFiUqOQ6mbrddpo2KT7Ea9RX8/2WzoCIqtk+rHKrOgUr45C5T3xjHEA7h8eOkcACuWh51xIfwc=

OpenBSD 7.1 errata 026, March 16, 2023:

Out of bounds accesses in libc resolver.

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

And then rebuild and install libc and static binaries:
    cd /usr/src/lib/libc
    make obj
    make
    make install
    cd /usr/src/bin
    make obj
    make
    make install
    cd /usr/src/sbin
    make obj
    make
    make install
    cd /usr/src/usr.bin/bgplg
    make obj
    make
    make install

Index: lib/libc/asr/asr_utils.c
===================================================================
RCS file: /cvs/src/lib/libc/asr/asr_utils.c,v
diff -u -p -u -r1.18 asr_utils.c
--- lib/libc/asr/asr_utils.c	23 Sep 2017 20:55:06 -0000	1.18
+++ lib/libc/asr/asr_utils.c	11 Mar 2023 15:44:38 -0000
@@ -123,7 +123,7 @@ dname_expand(const unsigned char *data, 
 
 	for (; (n = data[offset]); ) {
 		if ((n & 0xc0) == 0xc0) {
-			if (offset + 2 > len)
+			if (offset + 1 >= len)
 				return (-1);
 			ptr = 256 * (n & ~0xc0) + data[offset + 1];
 			if (ptr >= start)
@@ -133,7 +133,7 @@ dname_expand(const unsigned char *data, 
 			offset = start = ptr;
 			continue;
 		}
-		if (offset + n + 1 > len)
+		if (offset + n + 1 >= len)
 			return (-1);
 
 		if (dname_check_label(data + offset + 1, n) == -1)
Index: lib/libc/asr/getrrsetbyname_async.c
===================================================================
RCS file: /cvs/src/lib/libc/asr/getrrsetbyname_async.c,v
diff -u -p -u -r1.11 getrrsetbyname_async.c
--- lib/libc/asr/getrrsetbyname_async.c	23 Feb 2017 17:04:02 -0000	1.11
+++ lib/libc/asr/getrrsetbyname_async.c	10 Mar 2023 06:02:39 -0000
@@ -365,6 +365,9 @@ parse_dns_response(const u_char *answer,
 	struct dns_response *resp;
 	const u_char *cp;
 
+	if (size <= HFIXEDSZ)
+		return (NULL);
+
 	/* allocate memory for the response */
 	resp = calloc(1, sizeof(*resp));
 	if (resp == NULL)
@@ -431,14 +434,22 @@ parse_dns_qsection(const u_char *answer,
 	int i, length;
 	char name[MAXDNAME];
 
-	for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
+#define NEED(need) \
+	do { \
+		if (*cp + need > answer + size) \
+			goto fail; \
+	} while (0)
 
-		/* allocate and initialize struct */
-		curr = calloc(1, sizeof(struct dns_query));
-		if (curr == NULL) {
+	for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
+		if (*cp >= answer + size) {
+ fail:
 			free_dns_query(head);
 			return (NULL);
 		}
+		/* allocate and initialize struct */
+		curr = calloc(1, sizeof(struct dns_query));
+		if (curr == NULL)
+			goto fail;
 		if (head == NULL)
 			head = curr;
 		if (prev != NULL)
@@ -456,16 +467,20 @@ parse_dns_qsection(const u_char *answer,
 			free_dns_query(head);
 			return (NULL);
 		}
+		NEED(length);
 		*cp += length;
 
 		/* type */
+		NEED(INT16SZ);
 		curr->type = _getshort(*cp);
 		*cp += INT16SZ;
 
 		/* class */
+		NEED(INT16SZ);
 		curr->class = _getshort(*cp);
 		*cp += INT16SZ;
 	}
+#undef NEED
 
 	return (head);
 }
@@ -478,14 +493,23 @@ parse_dns_rrsection(const u_char *answer
 	int i, length;
 	char name[MAXDNAME];
 
-	for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
+#define NEED(need) \
+	do { \
+		if (*cp + need > answer + size) \
+			goto fail; \
+	} while (0)
 
-		/* allocate and initialize struct */
-		curr = calloc(1, sizeof(struct dns_rr));
-		if (curr == NULL) {
+	for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
+		if (*cp >= answer + size) {
+ fail:
 			free_dns_rr(head);
 			return (NULL);
 		}
+
+		/* allocate and initialize struct */
+		curr = calloc(1, sizeof(struct dns_rr));
+		if (curr == NULL)
+			goto fail;
 		if (head == NULL)
 			head = curr;
 		if (prev != NULL)
@@ -503,25 +527,31 @@ parse_dns_rrsection(const u_char *answer
 			free_dns_rr(head);
 			return (NULL);
 		}
+		NEED(length);
 		*cp += length;
 
 		/* type */
+		NEED(INT16SZ);
 		curr->type = _getshort(*cp);
 		*cp += INT16SZ;
 
 		/* class */
+		NEED(INT16SZ);
 		curr->class = _getshort(*cp);
 		*cp += INT16SZ;
 
 		/* ttl */
+		NEED(INT32SZ);
 		curr->ttl = _getlong(*cp);
 		*cp += INT32SZ;
 
 		/* rdata size */
+		NEED(INT16SZ);
 		curr->size = _getshort(*cp);
 		*cp += INT16SZ;
 
 		/* rdata itself */
+		NEED(curr->size);
 		curr->rdata = malloc(curr->size);
 		if (curr->rdata == NULL) {
 			free_dns_rr(head);
@@ -530,6 +560,7 @@ parse_dns_rrsection(const u_char *answer
 		memcpy(curr->rdata, *cp, curr->size);
 		*cp += curr->size;
 	}
+#undef NEED
 
 	return (head);
 }
Index: lib/libc/net/res_comp.c
===================================================================
RCS file: /cvs/src/lib/libc/net/res_comp.c,v
diff -u -p -u -r1.20 res_comp.c
--- lib/libc/net/res_comp.c	1 May 2016 15:17:29 -0000	1.20
+++ lib/libc/net/res_comp.c	10 Mar 2023 06:02:39 -0000
@@ -82,6 +82,9 @@ dn_expand(const u_char *msg, const u_cha
 	char *eom;
 	int len = -1, checked = 0;
 
+	if (comp_dn < msg || comp_dn >= eomorig)
+		return (-1);
+
 	dn = exp_dn;
 	cp = comp_dn;
 	if (length > HOST_NAME_MAX)
@@ -91,6 +94,9 @@ dn_expand(const u_char *msg, const u_cha
 	 * fetch next label in domain name
 	 */
 	while ((n = *cp++)) {
+		if (cp >= eomorig)	/* out of range */
+			return (-1);
+
 		/*
 		 * Check for indirection
 		 */
