]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/commitdiff
fixed bug #37705 Possible memory corruption in DNS query
authorSimon Goldschmidt <goldsimon@gmx.de>
Mon, 14 Jan 2013 17:03:23 +0000 (18:03 +0100)
committerSimon Goldschmidt <goldsimon@gmx.de>
Mon, 14 Jan 2013 17:03:23 +0000 (18:03 +0100)
CHANGELOG
src/core/dns.c

index 01ccaf7e66de4d93d5e0fd4693bbf2bbc2454509..6493dea451d0cc9bcb693aa632b3be3b10f28a5e 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -80,6 +80,9 @@ HISTORY
 
  ++ Bugfixes:
 
+  2013-01-14: Simon Goldschmidt
+  * dns.c: fixed bug #37705 Possible memory corruption in DNS query
   2013-01-11: Simon Goldschmidt
   * raw.c: fixed bug #38066 Raw pcbs can alter packet without eating it
 
index 788df7155d502a7f68edbc282ced854e710ddc0a..4e3a7deca6f9952b2ec220e4861f9b8414f2fcdf 100644 (file)
@@ -576,6 +576,7 @@ dns_send(u8_t numdns, const char* name, u8_t id)
   p = pbuf_alloc(PBUF_TRANSPORT, SIZEOF_DNS_HDR + DNS_MAX_NAME_LENGTH +
                  SIZEOF_DNS_QUERY, PBUF_RAM);
   if (p != NULL) {
+    u16_t realloc_size;
     LWIP_ASSERT("pbuf must be in one piece", p->next == NULL);
     /* fill dns header */
     hdr = (struct dns_hdr*)p->payload;
@@ -607,7 +608,9 @@ dns_send(u8_t numdns, const char* name, u8_t id)
     SMEMCPY(query, &qry, SIZEOF_DNS_QUERY);
 
     /* resize pbuf to the exact dns query */
-    pbuf_realloc(p, (u16_t)((query + SIZEOF_DNS_QUERY) - ((char*)(p->payload))));
+    realloc_size = (u16_t)((query + SIZEOF_DNS_QUERY) - ((char*)(p->payload)));
+    LWIP_ASSERT("p->tot_len >= realloc_size", p->tot_len >= realloc_size);
+    pbuf_realloc(p, realloc_size);
 
     /* connect to the server for faster receiving */
     udp_connect(dns_pcb, &dns_servers[numdns], DNS_SERVER_PORT);
@@ -860,12 +863,14 @@ memerr:
  * Queues a new hostname to resolve and sends out a DNS query for that hostname
  *
  * @param name the hostname that is to be queried
+ * @param hostnamelen length of the hostname
  * @param found a callback founction to be called on success, failure or timeout
  * @param callback_arg argument to pass to the callback function
  * @return @return a err_t return code.
  */
 static err_t
-dns_enqueue(const char *name, dns_found_callback found, void *callback_arg)
+dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found,
+            void *callback_arg)
 {
   u8_t i;
   u8_t lseq, lseqi;
@@ -910,7 +915,7 @@ dns_enqueue(const char *name, dns_found_callback found, void *callback_arg)
   pEntry->seqno = dns_seqno++;
   pEntry->found = found;
   pEntry->arg   = callback_arg;
-  namelen = LWIP_MIN(strlen(name), DNS_MAX_NAME_LENGTH-1);
+  namelen = LWIP_MIN(hostnamelen, DNS_MAX_NAME_LENGTH-1);
   MEMCPY(pEntry->name, name, namelen);
   pEntry->name[namelen] = 0;
 
@@ -945,13 +950,18 @@ dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback foun
                   void *callback_arg)
 {
   u32_t ipaddr;
+  size_t hostnamelen;
   /* not initialized or no valid server yet, or invalid addr pointer
    * or invalid hostname or invalid hostname length */
   if ((dns_pcb == NULL) || (addr == NULL) ||
-      (!hostname) || (!hostname[0]) ||
-      (strlen(hostname) >= DNS_MAX_NAME_LENGTH)) {
+      (!hostname) || (!hostname[0])) {
     return ERR_ARG;
   }
+  hostnamelen = strlen(hostname);
+  if (hostnamelen >= DNS_MAX_NAME_LENGTH) {
+    return ERR_ARG;
+  }
+  
 
 #if LWIP_HAVE_LOOPIF
   if (strcmp(hostname, "localhost")==0) {
@@ -972,7 +982,7 @@ dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback foun
   }
 
   /* queue query with specified callback */
-  return dns_enqueue(hostname, found, callback_arg);
+  return dns_enqueue(hostname, hostnamelen, found, callback_arg);
 }
 
 #endif /* LWIP_DNS */