Skip to content

Commit f068402

Browse files
ckhardinkartben
authored andcommitted
net: dns: swallow packets that have no useful records in them
There are some poorly compliant mdns responders on the network that will respond with zero counts on the answers and the additional records (in addition to the qdcount). So, this removes the checks in the unpack method since this is a "valid" DNS packet but the logic is already partially handled in the dns_read code already. An example packet can be seen in this decode 0000 33 33 00 00 00 fb 9a f8 c3 0c 07 0b 86 dd 60 07 33............`. 0010 c4 e4 00 14 11 ff fe 80 00 00 00 00 00 00 98 f8 ................ 0020 c3 ff fe 0c 07 0b ff 02 00 00 00 00 00 00 00 00 ................ 0030 00 00 00 00 00 fb 14 e9 14 e9 00 14 f1 64 00 00 .............d.. 0040 84 00 00 00 00 00 00 00 00 00 .......... User Datagram Protocol, Src Port: 5353, Dst Port: 5353 Source Port: 5353 Destination Port: 5353 Length: 20 Checksum: 0xf164 [unverified] [Checksum Status: Unverified] [Stream index: 2] [Stream Packet Number: 1] [Timestamps] UDP payload (12 bytes) Multicast Domain Name System (response) Transaction ID: 0x0000 Flags: 0x8400 Standard query response, No error 1... .... .... .... = Response: Message is a response .000 0... .... .... = Opcode: Standard query (0) .... .1.. .... .... = Authoritative: Server is an authority for domain .... ..0. .... .... = Truncated: Message is not truncated .... ...0 .... .... = Recursion desired: Don't do query recursively .... .... 0... .... = Recursion available: Server can't do recursive queries .... .... .0.. .... = Z: reserved (0) .... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server .... .... ...0 .... = Non-authenticated data: Unacceptable .... .... .... 0000 = Reply code: No error (0) Questions: 0 Answer RRs: 0 Authority RRs: 0 Additional RRs: 0 Signed-off-by: Charles Hardin <[email protected]>
1 parent d64e626 commit f068402

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

subsys/net/lib/dns/dns_pack.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,6 @@ int dns_unpack_response_header(struct dns_msg_t *msg, int src_id)
195195
{
196196
uint8_t *dns_header;
197197
uint16_t size;
198-
int qdcount;
199-
int ancount;
200198
int rc;
201199

202200
dns_header = msg->msg;
@@ -231,16 +229,6 @@ int dns_unpack_response_header(struct dns_msg_t *msg, int src_id)
231229

232230
}
233231

234-
qdcount = dns_unpack_header_qdcount(dns_header);
235-
ancount = dns_unpack_header_ancount(dns_header);
236-
237-
/* For mDNS (when src_id == 0) the query count is 0 so accept
238-
* the packet in that case.
239-
*/
240-
if ((qdcount < 1 && src_id > 0) || ancount < 1) {
241-
return -EINVAL;
242-
}
243-
244232
return 0;
245233
}
246234

subsys/net/lib/dns/resolve.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,15 @@ static int dispatcher_cb(struct dns_socket_dispatcher *my_ctx, int sock,
295295
}
296296

297297
ret = dns_read(ctx, dns_data, len, &dns_id, dns_cname, &query_hash);
298-
if (!ret) {
299-
/* We called the callback already in dns_read() if there
300-
* were no errors.
298+
if ((ret == 0) || (ret == DNS_EAI_NODATA)) {
299+
/* The callback is already called in dns_read() if there
300+
* were no errors indicated by a return of zero
301+
*
302+
* Also, in the case of no data records to process will
303+
* result in bypassing the callback. However, this goes
304+
* out a similar path as success to allow the request to
305+
* timeout or allow another packet to be processed that
306+
* might have records to validate.
301307
*/
302308
goto free_buf;
303309
}
@@ -1138,14 +1144,29 @@ int dns_validate_msg(struct dns_resolve_context *ctx,
11381144
goto quit;
11391145
}
11401146

1141-
if (dns_header_qdcount(dns_msg->msg) != 1) {
1147+
if (dns_header_qdcount(dns_msg->msg) < 1) {
11421148
/* For mDNS (when dns_id == 0) the query count is 0 */
11431149
if (*dns_id > 0) {
11441150
ret = DNS_EAI_FAIL;
11451151
goto quit;
11461152
}
11471153
}
11481154

1155+
if (dns_header_ancount(dns_msg->msg) < 1) {
1156+
/* there are no useful records in this message */
1157+
if (*dns_id > 0) {
1158+
ret = DNS_EAI_FAIL;
1159+
goto quit;
1160+
}
1161+
1162+
/*
1163+
* Assume another multicast responder might respond
1164+
* differently.
1165+
*/
1166+
ret = DNS_EAI_NODATA;
1167+
goto quit;
1168+
}
1169+
11491170
ret = dns_unpack_response_query(dns_msg);
11501171
if (ret < 0) {
11511172
if (ret == -ENOMEM) {

0 commit comments

Comments
 (0)