60 lines
2.1 KiB
Diff
60 lines
2.1 KiB
Diff
commit a7b60d23bbb56eaef59f4962e4140062e552600a
|
|
Author: Florian Weimer <fweimer@redhat.com>
|
|
Date: Fri Jun 19 18:22:20 2026 +0200
|
|
|
|
resolv: Fix buffer overreads in ns_sprintrrf (CVE-2026-6238)
|
|
|
|
Check that the RDATA payload does not require more than RDATALEN
|
|
bytes while processing it. The fixes cover A6, LOC records.
|
|
(CERT, TKEY, TSIG were fixed before, by switching to the generic
|
|
formatter.)
|
|
|
|
The vulnerable LOC record handling was first introduced before
|
|
glibc 2.0, in commit ee188d555b8c32ad9704a7440cab400af967292f.
|
|
|
|
CERT, TSIG, TKEY handling came with commit
|
|
b43b13ac2544b11f35be301d1589b51a8473e32b, released with glibc 2.2.
|
|
|
|
A6 record handling was introduced in commit
|
|
91633816430e7ec5a19fe3ff510a7c4822a9557e ("* resolv/ns_print.c
|
|
(ns_sprintrrf): Handle ns_t_a6 and ns_t_opt."), which went into glibc
|
|
2.7.
|
|
|
|
This fixes bug 34069.
|
|
|
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
|
|
|
diff --git a/resolv/ns_print.c b/resolv/ns_print.c
|
|
index ab68bf2cb7..f9dd086804 100644
|
|
--- a/resolv/ns_print.c
|
|
+++ b/resolv/ns_print.c
|
|
@@ -345,7 +345,8 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
|
case ns_t_loc: {
|
|
char t[255];
|
|
|
|
- /* XXX protocol format checking? */
|
|
+ if (rdlen != 16)
|
|
+ goto formerr;
|
|
(void) loc_ntoa(rdata, t);
|
|
T(addstr(t, strlen(t), &buf, &buflen));
|
|
break;
|
|
@@ -479,13 +480,14 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
|
|
|
/* address suffix: provided only when prefix len != 128 */
|
|
if (pbit < 128) {
|
|
- if (rdata + pbyte >= edata) goto formerr;
|
|
+ unsigned int bytelen = sizeof(a) - pbyte;
|
|
+ if (edata - rdata < bytelen) goto formerr;
|
|
memset(&a, 0, sizeof(a));
|
|
- memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte);
|
|
+ memcpy(&a.s6_addr[pbyte], rdata, bytelen);
|
|
if (inet_ntop (AF_INET6, &a, buf, buflen) == NULL)
|
|
return -1;
|
|
addlen(strlen(buf), &buf, &buflen);
|
|
- rdata += sizeof(a) - pbyte;
|
|
+ rdata += bytelen;
|
|
}
|
|
|
|
/* prefix name: provided only when prefix len > 0 */
|