From 769a2f832e10c03db979807d23ca5190026c53f6 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Tue, 2 Dec 2014 10:43:16 +0100 Subject: [PATCH 1/4] Fix for CERT VU#210620: randomize DNS request IDs for every request --- core/net/ip/resolv.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/core/net/ip/resolv.c b/core/net/ip/resolv.c index fab732af1..bc82dff17 100644 --- a/core/net/ip/resolv.c +++ b/core/net/ip/resolv.c @@ -227,9 +227,6 @@ struct dns_hdr { uint16_t numextrarr; }; -#define RESOLV_ENCODE_INDEX(i) (uip_htons(i+1)) -#define RESOLV_DECODE_INDEX(i) (unsigned char)(uip_ntohs(i-1)) - /** These default values for the DNS server are Google's public DNS: * */ @@ -264,6 +261,7 @@ struct namemap { #define STATE_DONE 4 uint8_t state; uint8_t tmr; + uint16_t id; uint8_t retries; uint8_t seqno; #if RESOLV_SUPPORTS_RECORD_EXPIRATION @@ -703,7 +701,8 @@ check_entries(void) } hdr = (struct dns_hdr *)uip_appdata; memset(hdr, 0, sizeof(struct dns_hdr)); - hdr->id = RESOLV_ENCODE_INDEX(i); + hdr->id = random_rand(); + namemapptr->id = hdr->id; #if RESOLV_CONF_SUPPORTS_MDNS if(!namemapptr->is_mdns || namemapptr->is_probe) { hdr->flags1 = DNS_FLAG1_RD; @@ -903,10 +902,13 @@ newdata(void) } else #endif /* RESOLV_CONF_SUPPORTS_MDNS */ { - /* The ID in the DNS header should be our entry into the name table. */ - i = RESOLV_DECODE_INDEX(hdr->id); - - namemapptr = &names[i]; + for(i = 0; i < RESOLV_ENTRIES; ++i) { + namemapptr = &names[i]; + if(namemapptr->state == STATE_ASKING && + namemapptr->id == hdr->id) { + break; + } + } if(i >= RESOLV_ENTRIES || i < 0 || namemapptr->state != STATE_ASKING) { PRINTF("resolver: DNS response has bad ID (%04X) \n", uip_ntohs(hdr->id)); From 19c7ae0dcd11f6ab86dc9ca26c064fdb8f839dcf Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Tue, 2 Dec 2014 10:43:31 +0100 Subject: [PATCH 2/4] Avoid compiler warning about unused variable --- core/net/ip/resolv.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/core/net/ip/resolv.c b/core/net/ip/resolv.c index bc82dff17..deac38e6c 100644 --- a/core/net/ip/resolv.c +++ b/core/net/ip/resolv.c @@ -504,8 +504,6 @@ start_name_collision_check(clock_time_t after) static unsigned char * mdns_write_announce_records(unsigned char *queryptr, uint8_t *count) { - struct dns_answer *ans; - #if NETSTACK_CONF_WITH_IPV6 uint8_t i; @@ -522,7 +520,6 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count) *queryptr++ = 0xc0; *queryptr++ = sizeof(struct dns_hdr); } - ans = (struct dns_answer *)queryptr; *queryptr++ = (uint8_t) ((NATIVE_DNS_TYPE) >> 8); *queryptr++ = (uint8_t) ((NATIVE_DNS_TYPE)); @@ -544,6 +541,8 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count) } } #else /* NETSTACK_CONF_WITH_IPV6 */ + struct dns_answer *ans; + queryptr = encode_name(queryptr, resolv_hostname); ans = (struct dns_answer *)queryptr; ans->type = UIP_HTONS(NATIVE_DNS_TYPE); @@ -601,8 +600,6 @@ mdns_prep_host_announce_packet(void) uint8_t total_answers = 0; - struct dns_answer *ans; - /* Be aware that, unless `ARCH_DOESNT_NEED_ALIGNED_STRUCTS` is set, * writing directly to the uint16_t members of this struct is an error. */ struct dns_hdr *hdr = (struct dns_hdr *)uip_appdata; From 990682229c05ea1aaf056db9c34acd87b99d8fcf Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Tue, 2 Dec 2014 10:43:46 +0100 Subject: [PATCH 3/4] Automatically initialize the resolv process --- core/net/ip/resolv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/net/ip/resolv.c b/core/net/ip/resolv.c index deac38e6c..8ada86897 100644 --- a/core/net/ip/resolv.c +++ b/core/net/ip/resolv.c @@ -1199,6 +1199,16 @@ PROCESS_THREAD(resolv_process, ev, data) PROCESS_END(); } /*---------------------------------------------------------------------------*/ +static void +init(void) +{ + static uint8_t initialized = 0; + if(!initialized) { + process_start(&resolv_process, NULL); + initialized = 1; + } +} +/*---------------------------------------------------------------------------*/ #if RESOLV_AUTO_REMOVE_TRAILING_DOTS static const char * remove_trailing_dots(const char *name) { @@ -1232,6 +1242,8 @@ resolv_query(const char *name) register struct namemap *nameptr = 0; + init(); + lseq = lseqi = 0; /* Remove trailing dots, if present. */ From d21835a61f5a39585c5fc6f176b88b4dbf60587e Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Tue, 2 Dec 2014 11:06:22 +0100 Subject: [PATCH 4/4] Don't do the debug printout if ipaddr is NULL --- core/net/ip/resolv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/net/ip/resolv.c b/core/net/ip/resolv.c index 8ada86897..5df53ecac 100644 --- a/core/net/ip/resolv.c +++ b/core/net/ip/resolv.c @@ -1380,7 +1380,8 @@ resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr) #if VERBOSE_DEBUG switch (ret) { - case RESOLV_STATUS_CACHED:{ + case RESOLV_STATUS_CACHED: + if(ipaddr) { PRINTF("resolver: Found \"%s\" in cache.\n", name); const uip_ipaddr_t *addr = *ipaddr;