If we're talking to upstream servers from a fixed port, specified by query-port
we create the fds to do this once, before dropping root, so that ports <1024 can be used.
But we call check_servers() before reading /etc/resolv.conf, so if the only servers
are in resolv.conf, at that point there will be no servers, and the fds get garbage
collected away, only to be recreated (but without root) after we read /etc/resolv.conf
Make pre-allocated server fds immortal, to avoid this problem.
If query-port is set, we create sockets bound to the wildcard address and the query port for
IPv4 and IPv6, but the IPv6 one fails, because is covers IPv4 as well, and an IPv4 socket
already exists (it gets created first). Set V6ONLY to avoid this.
I got reported bug in Fedora [1], that cname is broken in new releases.
At first I though this was false report, but there is still new
regression in cname handling.
Before, it accepted alias with trailing dot. Not it would accept only
target, but not alias.
cname=alias.,target
is no longer valid. The issue is it will count size to skip after
canonicalize. If that ignores trailing dot, next name would be "". And
that is invalid and refused, dnsmasq refuses to start.
I also think that any whitespace like tab should be possible after
comma. So this fixes also 30858e3b9b.
The way of accessing the list of available hashes on nettle was
vulnerable to breaking if the version of libnettle in use was
different to the version dnsmasq was compiled against.
Change to a new system if libnettle >= 3.4 is in use.
Older versions if nettle are still OK, once 3.4 is reached,
the ABi problem is fixed. Thanks to Petr Menšík for clues on this.
Use strlen to determine the length of the filename returned by
inotify, as in->len refers to the length of the buffer containing
the name, not the length of the name itself.
http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2018q1/011950.html
Signed-off-by: Andy Hawkins <andy@gently.org.uk>
Patch further modified by simon@thekelleys.org to avoid
out-of-bounds array access with an empty string, call strlen once,
and reverse order of filename verifcation and resolv-file test.
It's OK for NSEC records to be expanded from wildcards,
but in that case, the proof of non-existence is only valid
starting at the wildcard name, *.<domain> NOT the name expanded
from the wildcard. Without this check it's possible for an
attacker to craft an NSEC which wrongly proves non-existence
in a domain which includes a wildcard for NSEC.
RFC 4034 says:
[RFC2181] specifies that an RRset is not allowed to contain duplicate
records (multiple RRs with the same owner name, class, type, and
RDATA). Therefore, if an implementation detects duplicate RRs when
putting the RRset in canonical form, it MUST treat this as a protocol
error. If the implementation chooses to handle this protocol error
in the spirit of the robustness principle (being liberal in what it
accepts), it MUST remove all but one of the duplicate RR(s) for the
purposes of calculating the canonical form of the RRset.
We chose to handle this robustly, having found at least one recursive
server in the wild which returns duplicate NSEC records in the AUTHORITY
section of an answer generated from a wildcard record. sort_rrset() is
therefore modified to delete duplicate RRs which are detected almost
for free during the bubble-sort process.
Thanks to Toralf Förster for helping to diagnose this problem.
If all configured dns servers return refused in
response to a query; dnsmasq will end up in an infinite loop
retransmitting the dns query resulting into high CPU load.
Problem is caused by the dns refuse retransmission logic which does
not check for the end of a dns server list iteration in strict mode.
Having one configured dns server returning a refused reply easily
triggers this problem in strict order mode. This was introduced in
9396752c11
Thanks to Hans Dedecker <dedeckeh@gmail.com> for spotting this
and the initial patch.
Some of our Openstack users run quite large number of dnsmasq instances
on single host. They started hitting default limit of inotify socket
number on single system after upgrade to more recent version. System
defaults of sysctl fs.inotify.max_user_instances is 128. They reached
limit of 116 dnsmasq instances, then more instances failed to start.
I was surprised they have any use case for such high number of
instances. They use one dnsmasq for one virtual network.
I found simple way to avoid hitting low system limit. They do not use
resolv.conf for name server configuration or any dhcp hosts or options
directory. Created inotify socket is never used in that case. Simple
patch attached.
I know we can raise inotify system limit. I think better is to not waste
resources that are left unused.
The current logic is naive in the case that there is more than
one RRset in an answer (Typically, when a non-CNAME query is answered
by one or more CNAME RRs, and then then an answer RRset.)
If all the RRsets validate, then they are cached and marked as validated,
but if any RRset doesn't validate, then the AD flag is not set (good) and
ALL the RRsets are cached marked as not validated.
This breaks when, eg, the answer contains a validated CNAME, pointing
to a non-validated answer. A subsequent query for the CNAME without do
will get an answer with the AD flag wrongly reset, and worse, the same
query with do will get a cached answer without RRSIGS, rather than
being forwarded.
The code now records the validation of individual RRsets and that
is used to correctly set the "validated" bits in the cache entries.
The logic to determine is an EDNS0 header was added was wrong. It compared
the packet length before and after the operations on the EDNS0 header,
but these can include adding options to an existing EDNS0 header. So
a query may have an existing EDNS0 header, which is extended, and logic
thinks that it had a header added de-novo.
Replace this with a simpler system. Check if the packet has an EDSN0 header,
do the updates/additions, and then check again. If it didn't have one
initially, but it has one laterly, that's the correct condition
to strip the header from a reply, and to assume that the client
cannot handle packets larger than 512 bytes.