mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-13 17:00:49 +00:00
Fix heap OOB read in zone_status()
Credit to Yaohui Zhu (朱耀辉) for finding this. CNVD-C-2026-590208 applies. Summary zone_status() (src/dnssec.c:1867 in the 2.93 release; the same construct is in current git master, 2.93-29-gad92083) computes &name[name_start-2] in its backtrack loop without checking that name_start >= 2. When name_start == 1 the loop starts at name[-1] and dereferences it immediately; the guard (p != name) can never fire for p < name, so the scan walks backwards through the heap until it finds a '.' byte or hits an unmapped page. Under ASAN this is a deterministic heap-buffer-overflow READ; on a plain build the process dies with SIGSEGV. A single, ordinary query plus one crafted upstream reply is enough. My reproducer starts the ASAN binary with --dnssec and the root trust anchor, with a mock upstream; on the first query the mock answers with a captured crafted reply (a response carrying RRSIG(46), NSEC(47) with an empty/root owner name, and NSEC3(50) records in the authority section) and the process crashes on the first query.
This commit is contained in:
1 parent
a9880c595f
commit
f90df6c532
2 files changed
+5
-1
No files matched your search
@@ -9,6 +9,10 @@ version 2.94
|
|||||||
--no-dhcpv4-interface when using constructed address ranges.
|
--no-dhcpv4-interface when using constructed address ranges.
|
||||||
Thanks to David Nichols for discovery, diagnosis and patch.
|
Thanks to David Nichols for discovery, diagnosis and patch.
|
||||||
|
|
||||||
|
Fix heap OOB read in zone_status. Thanks to Yaohui Zhu (朱耀辉)
|
||||||
|
for spotting and reporting this. A crafted reply can crash dnsmasq.
|
||||||
|
CNVD-C-2026-590208 applies.
|
||||||
|
|
||||||
|
|
||||||
version 2.93
|
version 2.93
|
||||||
Fix a corner-case in DNSSEC validation with wildcards. If we have
|
Fix a corner-case in DNSSEC validation with wildcards. If we have
|
||||||
|
|||||||
+1
-1
@@ -1934,7 +1934,7 @@ static int zone_status(char *name, int class, char *keyname, time_t now)
|
|||||||
return STAT_INSECURE;
|
return STAT_INSECURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name_start == 0)
|
if (name_start <= 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (p = &name[name_start-2]; (*p != '.') && (p != name); p--);
|
for (p = &name[name_start-2]; (*p != '.') && (p != name); p--);
|
||||||
|
|||||||
Reference in new issue
Block a user