From 40fa4728eb0de88719c288aaf8793a37c1bb84f9 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 10 Dec 2015 16:08:43 +0100 Subject: [PATCH 1/2] resolved: discard any reply packet that contains a bogus name Only .in-addr.arpa and .local are considered local in mDNS, so discard the packet if anything else is thrown at us. --- src/resolve/resolved-mdns.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/resolve/resolved-mdns.c b/src/resolve/resolved-mdns.c index abe63d58c1d..d6973a69990 100644 --- a/src/resolve/resolved-mdns.c +++ b/src/resolve/resolved-mdns.c @@ -86,7 +86,7 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us } if (dns_packet_validate_reply(p) > 0) { - unsigned i; + DnsResourceRecord *rr; log_debug("Got mDNS reply packet"); @@ -107,11 +107,15 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us dns_scope_check_conflicts(scope, p); - for (i = 0; i < p->answer->n_rrs; i++) { - DnsResourceRecord *rr; + DNS_ANSWER_FOREACH(rr, p->answer) { + const char *name = DNS_RESOURCE_KEY_NAME(rr->key); DnsTransaction *t; - rr = p->answer->items[i].rr; + /* If the received reply packet contains ANY record that is not .local or .in-addr.arpa, + * we assume someone's playing tricks on us and discard the packet completely. */ + if (!(dns_name_endswith(name, "in-addr.arpa") > 0 || + dns_name_endswith(name, "local") > 0)) + return 0; t = dns_scope_find_transaction(scope, rr->key, false); if (t) From fe2dfc8b4947451f87fcae56f839ca84dde26453 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 10 Dec 2015 15:59:30 +0100 Subject: [PATCH 2/2] resolved: make sure the packet's transaction ID is always 0 for mDNS RFC6762, 18.1: In multicast query messages, the Query Identifier SHOULD be set to zero on transmission. --- src/resolve/resolved-dns-scope.c | 6 +++++- src/resolve/resolved-dns-transaction.c | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index 4d83ac597c4..bf49c51b5dd 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -818,7 +818,11 @@ static int dns_scope_make_conflict_packet( 0 /* (ad) */, 0 /* (cd) */, 0)); - random_bytes(&DNS_PACKET_HEADER(p)->id, sizeof(uint16_t)); + + /* For mDNS, the transaction ID should always be 0 */ + if (s->protocol != DNS_PROTOCOL_MDNS) + random_bytes(&DNS_PACKET_HEADER(p)->id, sizeof(uint16_t)); + DNS_PACKET_HEADER(p)->qdcount = htobe16(1); DNS_PACKET_HEADER(p)->arcount = htobe16(1); diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 90f07e6c4b9..05fce99679f 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -819,7 +819,6 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) { } DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount); - DNS_PACKET_HEADER(p)->id = t->id; /* Append known answer section if we're asking for any shared record */ if (add_known_answers) {