diff options
author | Sergey Bugaev <bugaevc@gmail.com> | 2021-02-19 14:50:23 +0100 |
---|---|---|
committer | Sergey Bugaev <bugaevc@gmail.com> | 2021-03-31 11:54:08 +0200 |
commit | 82d39576462ba66a4316307ce1ded97272e1245f (patch) | |
tree | ba465f2c3322d7dc0cafd8e543fb1b94d4ca81d5 /src/resolve | |
parent | resolved: add flags to DnsQuestion items (diff) | |
download | systemd-82d39576462ba66a4316307ce1ded97272e1245f.tar.xz systemd-82d39576462ba66a4316307ce1ded97272e1245f.zip |
resolved: fix mistaking QU bit for cache-flush bit
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
Diffstat (limited to 'src/resolve')
-rw-r--r-- | src/resolve/resolved-dns-packet.c | 27 | ||||
-rw-r--r-- | src/resolve/resolved-dns-packet.h | 2 | ||||
-rw-r--r-- | src/resolve/resolved-dns-rr.h | 8 | ||||
-rw-r--r-- | src/resolve/resolved-mdns.c | 2 |
4 files changed, 18 insertions, 21 deletions
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index ab1b658237..a197f94bcf 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -627,7 +627,7 @@ int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, const DnsAnswer if (r < 0) goto fail; - class = flags & DNS_ANSWER_CACHE_FLUSH ? k->class | MDNS_RR_CACHE_FLUSH : k->class; + class = flags & DNS_ANSWER_CACHE_FLUSH ? k->class | MDNS_RR_CACHE_FLUSH_OR_QU : k->class; r = dns_packet_append_uint16(p, class, NULL); if (r < 0) goto fail; @@ -1628,12 +1628,12 @@ static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t siz int dns_packet_read_key( DnsPacket *p, DnsResourceKey **ret, - bool *ret_cache_flush, + bool *ret_cache_flush_or_qu, size_t *ret_start) { _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder; _cleanup_free_ char *name = NULL; - bool cache_flush = false; + bool cache_flush_or_qu = false; uint16_t class, type; int r; @@ -1653,11 +1653,11 @@ int dns_packet_read_key( return r; if (p->protocol == DNS_PROTOCOL_MDNS) { - /* See RFC6762, Section 10.2 */ + /* See RFC6762, sections 5.4 and 10.2 */ - if (type != DNS_TYPE_OPT && (class & MDNS_RR_CACHE_FLUSH)) { - class &= ~MDNS_RR_CACHE_FLUSH; - cache_flush = true; + if (type != DNS_TYPE_OPT && (class & MDNS_RR_CACHE_FLUSH_OR_QU)) { + class &= ~MDNS_RR_CACHE_FLUSH_OR_QU; + cache_flush_or_qu = true; } } @@ -1672,8 +1672,8 @@ int dns_packet_read_key( *ret = key; } - if (ret_cache_flush) - *ret_cache_flush = cache_flush; + if (ret_cache_flush_or_qu) + *ret_cache_flush_or_qu = cache_flush_or_qu; if (ret_start) *ret_start = rewinder.saved_rindex; @@ -2221,15 +2221,12 @@ static int dns_packet_extract_question(DnsPacket *p, DnsQuestion **ret_question) for (i = 0; i < n; i++) { _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL; - bool cache_flush; + bool qu; - r = dns_packet_read_key(p, &key, &cache_flush, NULL); + r = dns_packet_read_key(p, &key, &qu, NULL); if (r < 0) return r; - if (cache_flush) - return -EBADMSG; - if (!dns_type_is_valid_query(key->type)) return -EBADMSG; @@ -2240,7 +2237,7 @@ static int dns_packet_extract_question(DnsPacket *p, DnsQuestion **ret_question) /* Already in the Question, let's skip */ continue; - r = dns_question_add_raw(question, key, 0); + r = dns_question_add_raw(question, key, qu ? DNS_QUESTION_WANTS_UNICAST_REPLY : 0); if (r < 0) return r; } diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h index 7b2abe3e76..e9820795c0 100644 --- a/src/resolve/resolved-dns-packet.h +++ b/src/resolve/resolved-dns-packet.h @@ -233,7 +233,7 @@ int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start); int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start); int dns_packet_read_raw_string(DnsPacket *p, const void **ret, size_t *size, size_t *start); int dns_packet_read_name(DnsPacket *p, char **ret, bool allow_compression, size_t *start); -int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, bool *ret_cache_flush, size_t *start); +int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, bool *ret_cache_flush_or_qu, size_t *start); int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_flush, size_t *start); void dns_packet_rewind(DnsPacket *p, size_t idx); diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index ab48ea5f2a..43bbcb3073 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -16,12 +16,12 @@ typedef struct DnsResourceRecord DnsResourceRecord; typedef struct DnsTxtItem DnsTxtItem; /* DNSKEY RR flags */ -#define DNSKEY_FLAG_SEP (UINT16_C(1) << 0) -#define DNSKEY_FLAG_REVOKE (UINT16_C(1) << 7) -#define DNSKEY_FLAG_ZONE_KEY (UINT16_C(1) << 8) +#define DNSKEY_FLAG_SEP (UINT16_C(1) << 0) +#define DNSKEY_FLAG_REVOKE (UINT16_C(1) << 7) +#define DNSKEY_FLAG_ZONE_KEY (UINT16_C(1) << 8) /* mDNS RR flags */ -#define MDNS_RR_CACHE_FLUSH (UINT16_C(1) << 15) +#define MDNS_RR_CACHE_FLUSH_OR_QU (UINT16_C(1) << 15) /* DNSSEC algorithm identifiers, see * http://tools.ietf.org/html/rfc4034#appendix-A.1 and diff --git a/src/resolve/resolved-mdns.c b/src/resolve/resolved-mdns.c index 2857b58e89..4b6df10614 100644 --- a/src/resolve/resolved-mdns.c +++ b/src/resolve/resolved-mdns.c @@ -10,7 +10,7 @@ #include "resolved-mdns.h" #include "sort-util.h" -#define CLEAR_CACHE_FLUSH(x) (~MDNS_RR_CACHE_FLUSH & (x)) +#define CLEAR_CACHE_FLUSH(x) (~MDNS_RR_CACHE_FLUSH_OR_QU & (x)) void manager_mdns_stop(Manager *m) { assert(m); |