Update embedded dnsmasq to v2.93#2890
Conversation
A malformed DHCP request can cause out-bounds memory reads, and probably SEGV. Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
…ions. A general rewrite and consolidation of the code that determines if an incoming TCP connection is allowed, based on --address and --interface. This was prompted by a bug found by Sławomir Zborowski where a TCP connection for a valid IPv4 address on one interface which arrived via a second interface which didn't have an IPv4 address would be wrongly rejected. Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
These can't be held forever by a client that opens a connection and then sends nothing, but we can still be DoSsed by a server which accepts a connection and never replies. If the TCP process times out, it sends that information to the parent so that the UDP query can be unblocked. As the TCP timeout is 150s it's highly unlikely that any client will still be waiting, but the point is to free resources. Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
If we have a wildcard record *.example.com and recieve a query for a.example.com then that's OK, but we have to check that there isn't an actual a.example.com record. The corner case is when we get a query for *.example.com in that case the non-existence check is not required, but was being done. Thanks to Jan Breig for spotting this. Signed-off-by: Dominik <dl6er@dl6er.de>
FreeBSD 15.0 has added Linux-compatible inotify support, so enable it by looking if the version matches. Since FreeBSD inotify has seen a few bug fixes in 2025H2, so only enable it if __FreeBSD_version >= 1500068. The latter can be checked through osreldate.h or sys/param.h; the latter defines more macros that clash with dnsmasq's, such as MIN and MAX, so use the former. Signed-off-by: Dominik <dl6er@dl6er.de>
The presence of wrong RRSIG RRs in replies causes DNSSEC validation to fail even when the RRs do not require validation because the zone is unsigned. This patch solves the problem and tidies up the logic. Included is some fixes for hostname_issubdomain() which suffered some confusions about argument order :) I've clarified that and checked every to the function to make sure they are using the correct argument order. Note that, at the time of this commit, Google DNS appears to have the same bug, so if you're using 8.8.8.8 or friends as upstream, resolving the broken zones (eg rivcoed.org) will still fail. Thanks to Petr Menšík for the bug report. Signed-off-by: Dominik <dl6er@dl6er.de>
This may be useful for embedded systems for example: log-queries without only_failed places a heavy load on the NAND flash memory. At the same time, logging requests is necessary to troubleshoot network issues. Signed-off-by: Dominik <dl6er@dl6er.de>
If we're doing DNSSEC validation and fail because the upstream reply to our query is SERVFAIL, log this as the reason in validation result line. This will make maintainers lives easier when they get reports of "wrong" validation failure, which is sometimes an upstream problem. Signed-off-by: Dominik <dl6er@dl6er.de>
A CNAME reply to a DNSSEC query was confusing the validation logic. It now accepts a signed CNAME reply to a DS query as proof that no DS exists at the domain. This fixes the DS/zone break detection logic. Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
This was functionally correct, but every call malloced a new buffer and freed the previous one, rather than only doing that when the buffer needed expansion. Signed-off-by: Dominik <dl6er@dl6er.de>
Log all blocks malloced and all blocks freed. Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
This fixes the plethora of 64k buffers that got allocated when doing DNSSEC over TCP. By using the UDP buffer is pass the query into tcp_talk() and allowing tcp_talk to allocate its output buffer one the size of the reply is known, we only need to allocate as much memory as is required. The final reply to the TCP query still needs the 64k buffer because answer_request() and answer_auth() are not capable of extending their output buffers. Signed-off-by: Dominik <dl6er@dl6er.de>
In the DNS TCP code, there are a couple of places where we have a buffer containing a message which we need to send via TCP. The DNS protocol is that this is sent as <16-bit length in network order><message> Making two write calls, one for the length and one for the message causes the TCP stack to send two packets, one for each. A single packet containing both is preferable from a performance POV. Implement a scatter-gather version of our read_write() wrapper and use it where necessary to send TCP DNS messages. Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
…p of free/strdup Signed-off-by: Dominik <dl6er@dl6er.de>
This almost certainly never worked and was never use, and it's rendered obsolete in RFC 9915. Signed-off-by: Dominik <dl6er@dl6er.de>
Anything sent by a client must be multicast. A relay can unicast to a server. Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
While this won't do harm on systems that do 2's completement, it triggers the compilers' undefined-behavior sanitizer and fixes sanitizer error such as the one below (where the 1694... will vary) and is distracting while debugging. dnssec.c:1427:12: runtime error: left shift of 1694604366 by 1 places cannot be represented in type 'int' Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
If iovcnt is exhausted and the first vector element's operation is satisfied, the while loop will read past the end of the iovec array. This triggers the address sanitizer and leads to undefined program state. Avoid reading too far. Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
Stop using the namebuff buffer to read config file lines. This reduced in size in 014e909f787e808bb35daa546d3f8f3663918de2 and caused regressions. We now resize the buffer as needed, so there is no practical limit. Use the same code to remove the same limit when reading /etc/ethers and /etc/resolv.conf. Also when copying output from the lease-change script into the log. Thanks to Kevin Darbyshire-Bryant for finding the regresssion. Signed-off-by: Dominik <dl6er@dl6er.de>
commit 1269f074f86bb959863012063060a3a082d37dc4 broke hostname_issubdomain() and then accidentally fixed some of the problems by inverting the argument order in the new uses of the function it introduced. All the pre-existing calls to hostname_issubdomain() were left in a non-working state. This fixes hostname_issubdomain() back to the state before 1269f074f86bb959863012063060a3a082d37dc4, adds some logic to give correct answers when comparing to the root domain, and gets right the new calls to hostname_issubdomain() added in 1269f074f86bb959863012063060a3a082d37dc4 Thanks to Jean Thomas for spotting this problem. Signed-off-by: Dominik <dl6er@dl6er.de>
Before this fix, the code could read a couple of bytes beyond valid data when an invalid too-short packet was recieved. Thanks to Sokhna Walo DIAKHATE <sokhnawalodiakhate@esp.sn> for the bug report. Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
This fixes an OOB write caused by bad pointer arithmetic calculating the pointer-to-end-of-packet used before. Thanks to Donghyeon Jeong for spotting the bug. Signed-off-by: Dominik <dl6er@dl6er.de>
Also ripple effects for most of its callers. This fixes an OOB write caused by bad pointer arithmetic calculating the pointer-to-end-of-packet used before. Thanks to Donghyeon Jeong for spotting the bug. Signed-off-by: Dominik <dl6er@dl6er.de>
Full credit to Jerry Tom <goonsomeway@gmail.com> for finding this. When DNSSEC validation falls back to TCP (via a forked child process), the parent uses a uid-based check to detect whether a frec has been freed and reused before the child returns. It doesn't, however check for the more likely scenario which is that the frec has simply been freed via the timeout path in get_new_frec(). This leads to a use-after-free on an already freed frec. Signed-off-by: Dominik <dl6er@dl6er.de>
The current local address range is fd00::/8, but RFC 4193 para 3.1/3.2 reserves fc00::/8 for future use as local addresses, so add that to the list. Thanks to Michalis Vasileiadis for spotting this omission. Signed-off-by: Dominik <dl6er@dl6er.de>
print_mac() used to output into caller-supplied buffer with no length checking. The various callers supplied different length buffers and did their own, ad-hoc, length checking before calling print_mac(). This was an accident waiting to happen and it had actually happened in couple of places, with buffer overflows possible. print_mac() now returns the address of its own buffer, which is grown as required. Thanks to Nicholas Carlini <npc@anthropic.com> for spotting this problem. Signed-off-by: Dominik <dl6er@dl6er.de>
Assigning the result of getc() to a char makes comparing it to EOF unreliable, at the very least. You're never too old to make newbie mistakes. Thanks to Sebastian Gottschall for spotting this. Signed-off-by: Dominik <dl6er@dl6er.de>
If we stop reading a file before getting to the end, get_line_alloc() will not clean up the memory it allocated. Give get_line_alloc() the ability to do a forced cleanup by calling it with a NULL file, and use that ability where we stop reading a file early. Also clear the state variables when we free the memory, to pre-empt use-after-free. Signed-off-by: Dominik <dl6er@dl6er.de>
It turns out that subtracting NULL from a pointer to turn it into an integer is not a good idea, because subtracting a NULL pointer is undefined behaviour in C. The correct way to do this is simply to cast the pointer to uintptr_t. The only fly in this ointment is that the C standard does not mandate support for uintptr_t. In practice, I doubt anyone is running dnsmasq on the long-dead architectures where this might be a problem. Thanks to Matthias Andree for the heads-up. Signed-off-by: Dominik <dl6er@dl6er.de>
get_rdata() contains another instance of a crash caused by a false value of RDLEN in a resource-record. An RR containing name which is longer than the rdlen of the RR can get get_rdata into a state where it calculates the length of the data following the name as a negative number which is then promoted to a very large positive number, and causing SIGSEGV. This can be triggered by crafted packets from malicous DNS servers, but only when DNSSEC validation is enabled. The attack packets do not have to be correctly DNSSEC signed. Thanks to Tristan G. for spotting this problem. Also fix error handling for RRs with a fixed size fields in the specification where the rrsize indicates that there are zero bytes in that position. Signed-off-by: Dominik <dl6er@dl6er.de>
Signed-off-by: Dominik <dl6er@dl6er.de>
|
Conflicts have been resolved. |
|
This will soon be released as FTL v6.7 |
…print_mac()'s buffer handling Also fix add_pseudoheader() call sites for the v2.93 size_t out_size signature. Signed-off-by: DL6ER <dl6er@dl6er.de>
|
Are these errors in the tests expected? |
Signed-off-by: Dominik <dl6er@dl6er.de>
|
Fixed |
rdwebdesign
left a comment
There was a problem hiding this comment.
Approved.
Note:
All 6 CVE fixes were already in v2.92.2 (master branch hotfix).
Now v2.93 will add them to development branch.
Doesn't development also currently have v2.92.2 via #2889? |
|
TL;DR: Yes, both The fixes that are part of v2.92.2 were, however, only minimal backwards-compatible fixes for the given vulnerabilities. The v2.93 rewrites some of the affected features in a way to avoid (instead of circumvent) the underlying issues. This makes the code smaller, use less memory and also fix some additional edge-cases and non-critical bugs. |
What does this implement/fix?
Update embedded dnsmasq to released v2.93
Highlights
Security
(all of these have already been merged into
masterand are released separately)rdlen.--add-subnet.extract_addresses()via crafted RRrdlen.DNSSEC correctness
DHCP and inotify
Further fixes and improvements made by the Pi-hole team
dump: checklseek()return in pcap record-counting loop.domain: fixstrncatbuffer-size argument inis_rev_synth().lease: checkparse_hex()return value before use as length.edns0: bounds-check option length beforememcmpincheck_source().rfc3315: fix integer underflow / heap overflow inlog6_opts STATUS_CODE.dhcp-common: fix OOB reads in DHCPv6option_string()decoders.dhcp-common: bounds-check label index before reading inOT_RFC1035_NAMEdecoder.rfc2131: fix off-by-one in BOOTP filename netid NUL termination.helper: fix OOB read ingrab_extradata_luabounds check.prettyprint_time(): NUL-terminate buf whent == 0.rand64()must share globaloutleftwithrand16()/rand32().reply_query(): move fd-match guard out of loop.expand_workspace_real(): zero the correct byte count.Related issue or feature (if applicable): N/A
Pull request in docs with documentation (if applicable): N/A
By submitting this pull request, I confirm the following:
git rebase)Checklist:
developmentbranch.