With some versions of the compiler, the _cleanup_ attr makes it think
the variable might be freed/closed when uninitialized, even though it
cannot happen. The added cost is small enough to be worth the benefit,
and optimized builds will help reduce it even further.
The issue was introduced in the refactoring in 775ae35403.
We would pass an initialized value to a helper function. We would only *use*
it if it was initialized. But the mere passing of an unitialized variable is
UB, so let's not do that. This silences a gcc warning.
RFC 6762 defines the top bit in RRs to mean cache flush (section 10.2),
and the top bit in questions to mean that a unicast reply is wanted
(section 5.4).
dns_packet_read_key() is used for parsing both questions and RRs.
When called from dns_packet_extract_question(), the top bit being set
should not result in the packet being rejected as invalid.
Fixes https://github.com/systemd/systemd/issues/17973
Check the return code from gcrypt's functions. In some
cases just log, as it shoulnd't really happen.
Fixes various Coverity issues:
CID #1444702
CID #1444704
CID #1444706
CID #1444711
CID #1444712
CID #1444713
let's make sure we set the "aa" bit in the stub only if we answer with
fully authoritative data. For this ensure:
1. Either all data is synthetic, including all CNAME/DNAME redirects
2. Or all data comes from the local trust anchor or the local zones
(i.e. not the network or the cache)
Follow-up for 4ad017cda5
This fixes resetting of initial_jitter_elapsed: the first time the timer
hits after initial_jitter_scheduled is set we need to mark things as
elapsed.
(Also improve log messages around this while we are at it)
This adds the same line to most of our .conf files.
Not for systemd/user.conf though, since we can't correctly display it right
now:
$ systemd-analyze cat-config --user systemd/user.conf
Option --user is not supported for cat-config right now.
For sysusers.d, tmpfiles.d, rules.d, etc, there is no single file. Maybe
we should short READMEs in /usr/lib/sysusers.d, /usr/lib/tmpfiles.d, etc.?
Inspired by #19118.
When following CNAME/DNAME redirects in the stub we currently first
iterate through the packet and pick up what we can use (in
dns_stub_collect_answer_by_question() and friends), following all
CNAMEs/DNAMEs, and would then issue dns_query_process_cname() to move
the DnsQuery object forward too, where we'd then possibly restart
the query and pick things up again, as above.
There's one thought error in this though: dns_query_process_cname()
tries to be smart and will internally follow not just a single
CNAME/DNAME redirect, but a chain of them if they are contained inside
the same packet until we reach the point where the answer is not
included in the packet anymore, where we'd restart the query. This was
great as long as we only focussed on the D-Bus and Varlink resolver
APIs, since there the CNAME/DNAME chain in the middle doesn't actually
matter, we just return information about the final name of the RR and
its content, and aren't interested in the chain to it. For the DNS stub
this is different however: there we need to place the full CNAME/DNAME
chain (and all the appropriate metadata RRs) in the stub reply.
Hence rework this so that we build on the fact that the previous commit
split dns_query_process_cname() in two:
1. dns_query_process_cname_one() will do exactly one CNAME/DNAME
redirect step. This will be called by the stub, so that we can pick
up matching RRs for every single step along the way.
2. dns_query_process_cname_many() will follow a chain as long as that's
possible within the same packet. It's thus pretty much identical to
the old dns_query_process_cname() call. This is what we now use in
the D-Bus and Varlink APIs. dns_query_process_cname_many() is
basically just a loop around dns_query_process_cname_one().
Any logic to follow and pick up RRs manually in the stub along the
CNAME/DNAME path is now dropped (i.e.
dns_stub_collect_answer_by_question() becomes trivially simple again),
we solely rely on dns_query_process_cname_one() to follow CNAME/DNAME
now: each step followed by a full call of dns_stub_assign_sections() to
copy out the RRs that matter.
Net result: things are a bit simpler again, as the only place we follow
CNAME/DNAME redirects is DnsQuery again, and stub answers are always
complete: they contain all CNAME/DNAME RRs on the way including all
their metadata we might pick up in the other sections.
This does some refactoring: the dns_query_process_cname() function
becomes two: dns_query_process_cname_one() and
dns_query_process_cname_many(). The former will process exactly one
CNAME chain element, the latter will follow a chain for as long as
possible within the current packet.
dns_query_process_cname_many() is mostly identical to the old
dns_query_process_cname(), and all existing code is moved over to using
that.
This is mostly preparation for the next commit, where we make direct use
of dns_query_process_cname_one().
This also renames the DNS_QUERY_RESTARTED return value to
DNS_QUERY_CNAME. That's because in the dns_query_process_cname_many()
case as before if we return this we restarted the query in case we
reached the end of the chain without a conclusive answer, as before. But
in dns_query_process_cname_one() we'll only go one step anyway, and
leave restarting if needed to the caller. Hence DNS_QUERY_RESTARTED is a
bit of a misnomer in that case.
This also gets rid of the weird tail recursion in
dns_query_process_cname() and replaces it with an explicit loop in
dns_query_process_cname_many(). The old recursion wasn't a security
issue since we put a limit on the number of CNAMEs we follow anyway, but
it's still icky to scale stack use by that.
Previously we'd stick all answer sections RRs we acquired into
the authoritative section if we didn't find them directly answering our
question. Let's put them into additional instead. The authoritative
section should hence only include what comes from the upstream
authoritative section, and nothing else.
Previously we'd iterate through the RRs of an mDNS reply and then find
exactly one matching transaction on our scope for it, and pass it as
reply to that. If multiple RRs of the same packet match we'd pas the
packet multiple times to the transaction even.
This all doesn't really work anymore since there can be multiple open
transactions for the same key (with different flags), and it's kinda
ugly anywy. Hence let's turn this around: let's iterate through the
transactions and check if any of the included RRs match it, and if so
pass the packet to that transaction exactly once.
This speeds up mDNS a bit, since previously we'd oftentimes fail to find
all suitable transactions for an mDNS reply (because there can be
multiple transactions for the same RR key with different flags, and we
checked exactly one flag combination). Which would then mean the
transaction would time out, and be retried – at which point the cache
would be populated and thus it would still succeed, but only after this
timeout. With this fix this is corrected: every transaction that matches
will get the reply, instantly as we get it.
This is inspired by a recent thread on fedora-devel: it's noteworthy
when we switch to the fallback servers, since it might (or might not)
indicate some configuration problem.
Fixes: #18788
When we checking if the responses we collected for a DnsQuery are
sufficient to complete it we previously only check if one of the
collected response RRs matches at least one of the question RR keys.
This changes the logic to require that there must be at least one
response RR matched *each* of the question RR keys before considering
the answer complete.
Otherwise we might end up accepting an A reply as complete answer for an
A/AAAA query and vice versa, but we want to make sure we wait until we
get a reply on both types before returning this to the user in all
cases.
This has been broken for basically forever, but didn't surface until
b1eea703e0 since until then we'd basically
ignore the auxiliary RRs included in CNAME/DNAME replies. Once that
commit was made we'd start using the auxiliary RRs included in
CNAME/DNAME replies but those typically included only A or only AAAA
which we then took for complete.
Fixe: #19049
rr is asserted upon a few lines above, no need to check for null.
Coverity-found issue, CID 1450844
CID 1450844: Null pointer dereferences (REVERSE_INULL)
Null-checking "rr" suggests that it may be null, but it has already
been dereferenced on all paths leading to the check.