dnsmasq: fix CVE-2026-4890

A Denial of Service (DoS) vulnerability in the DNSSEC
validation of dnsmasq allows remote attackers to cause
a denial of service via a crafted DNS packet.

Reference:
[ https://nvd.nist.gov/vuln/detail/CVE-2026-4890 ]

Signed-off-by: Abhishek Bachiphale <Abhishek.Bachiphale@windriver.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
Abhishek Bachiphale
2026-05-18 22:43:32 +05:30
committed by Khem Raj
parent a53328688a
commit 78162615f5
2 changed files with 51 additions and 0 deletions
@@ -16,6 +16,7 @@ SRC_URI = "http://www.thekelleys.org.uk/dnsmasq/${@['archive/', ''][float(d.getV
file://dnsmasq-noresolvconf.service \
file://dnsmasq-resolved.conf \
file://CVE-2026-2291.patch \
file://CVE-2026-4890.patch \
"
SRC_URI[sha256sum] = "fd908e79ff37f73234afcb6d3363f78353e768703d92abd8e3220ade6819b1e1"
@@ -0,0 +1,50 @@
commit 4fdb707633afe8028118bcaf39b4882f634b5999
Author: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri Apr 10 16:24:02 2026 +0100
Fix NSEC bitmap parsing infinite loop. CVE-2026-4890
Report from Royce M <royce@xchglabs.com>.
Location: dnssec.c:1290-1306, dnssec.c:1450-1463
The bitmap window iteration advances by p[1] instead of p[1]+2
(missing the 2-byte window header). With bitmap_length=0, both rdlen and p are
unchanged, causing an infinite loop and dnsmasq stops responding to all queries.
Reachable before RRSIG validation
(confirmed by the source comment at line 2125), so no valid
DNSSEC signatures are needed.
CVE: CVE-2026-4890
Upstream-Status: Backport [ https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=7b151eb60609a0139474918222806f9bcfb4fe71 ]
Signed-off-by: Abhishek Bachiphale <Abhishek.Bachiphale@windriver.com>
diff --git a/src/dnssec.c b/src/dnssec.c
index 4bb0495..3951620 100644
--- a/src/dnssec.c
+++ b/src/dnssec.c
@@ -1348,8 +1348,8 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
break; /* finished checking */
}
- rdlen -= p[1];
- p += p[1];
+ rdlen -= p[1] + 2;
+ p += p[1] + 2;
}
return 0;
@@ -1512,8 +1512,8 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige
break; /* finished checking */
}
- rdlen -= p[1];
- p += p[1];
+ rdlen -= p[1] + 2;
+ p += p[1] + 2;
}
return 1;