<p>George Joseph has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/10641">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">AST-2018-010: Fix length of buffer needed for SRV and NAPTR results<br><br>When dn_expand was being called on SRV and NAPTR results, the<br>return value was being used to calculate the size of the buffer<br>needed to store the host names.  Since dn_expand returns the<br>length of the COMPRESSED name the buffer could be too short<br>to hold the EXPANDED name.  The expanded name is NULL terminated<br>so using strlen() is the correct way to determine the length<br>actually needed for the buffer.<br><br>ASTERISK-28127<br>Reported by: Jan Hoffmann<br><br>patches:<br>  patch.diff submitted by janhoffmann (license 6986)<br><br>Change-Id: I4d35d6c431c6c6836cb61d37b1378cc47f0b414d<br>---<br>M main/dns_naptr.c<br>M main/dns_srv.c<br>2 files changed, 20 insertions(+), 6 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/41/10641/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/main/dns_naptr.c b/main/dns_naptr.c</span><br><span>index 5490b55..4d67816 100644</span><br><span>--- a/main/dns_naptr.c</span><br><span>+++ b/main/dns_naptr.c</span><br><span>@@ -393,6 +393,7 @@</span><br><span>      int replacement_size;</span><br><span>        const char *end_of_record;</span><br><span>   enum flags_result flags_res;</span><br><span style="color: hsl(120, 100%, 40%);">+  size_t naptr_len;</span><br><span> </span><br><span>        ptr = dns_find_record(data, size, query->result->answer, query->result->answer_size);</span><br><span>    ast_assert(ptr != NULL);</span><br><span>@@ -435,7 +436,14 @@</span><br><span>              return NULL;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   replacement_size = dn_expand((unsigned char *)query->result->answer, (unsigned char *) end_of_record, (unsigned char *) ptr, replacement, sizeof(replacement) - 1);</span><br><span style="color: hsl(120, 100%, 40%);">+     /*</span><br><span style="color: hsl(120, 100%, 40%);">+     * The return value from dn_expand represents the size of the replacement</span><br><span style="color: hsl(120, 100%, 40%);">+      * in the buffer which MAY be compressed.  Since the expanded replacement</span><br><span style="color: hsl(120, 100%, 40%);">+      * is NULL terminated, you can use strlen() to get the expanded size.</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+   replacement_size = dn_expand((unsigned char *)query->result->answer,</span><br><span style="color: hsl(120, 100%, 40%);">+            (unsigned char *) end_of_record, (unsigned char *) ptr,</span><br><span style="color: hsl(120, 100%, 40%);">+               replacement, sizeof(replacement) - 1);</span><br><span>       if (replacement_size < 0) {</span><br><span>               ast_log(LOG_ERROR, "Failed to expand domain name: %s\n", strerror(errno));</span><br><span>                 return NULL;</span><br><span>@@ -475,7 +483,9 @@</span><br><span>           return NULL;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   naptr = ast_calloc(1, sizeof(*naptr) + size + flags_size + 1 + services_size + 1 + regexp_size + 1 + replacement_size + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+   naptr_len = sizeof(*naptr) + size + flags_size + 1 + services_size + 1</span><br><span style="color: hsl(120, 100%, 40%);">+                + regexp_size + 1 + strlen(replacement) + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+  naptr = ast_calloc(1, naptr_len);</span><br><span>    if (!naptr) {</span><br><span>                return NULL;</span><br><span>         }</span><br><span>diff --git a/main/dns_srv.c b/main/dns_srv.c</span><br><span>index b562e32..e11c84e 100644</span><br><span>--- a/main/dns_srv.c</span><br><span>+++ b/main/dns_srv.c</span><br><span>@@ -73,7 +73,13 @@</span><br><span>          return NULL;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   host_size = dn_expand((unsigned char *)query->result->answer, (unsigned char *) end_of_record, (unsigned char *) ptr, host, sizeof(host) - 1);</span><br><span style="color: hsl(120, 100%, 40%);">+  /*</span><br><span style="color: hsl(120, 100%, 40%);">+     * The return value from dn_expand represents the size of the replacement</span><br><span style="color: hsl(120, 100%, 40%);">+      * in the buffer which MAY be compressed.  Since the expanded replacement</span><br><span style="color: hsl(120, 100%, 40%);">+      * is NULL terminated, you can use strlen() to get the expanded size.</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+   host_size = dn_expand((unsigned char *)query->result->answer,</span><br><span style="color: hsl(120, 100%, 40%);">+           (unsigned char *) end_of_record, (unsigned char *) ptr, host, sizeof(host) - 1);</span><br><span>     if (host_size < 0) {</span><br><span>              ast_log(LOG_ERROR, "Failed to expand domain name: %s\n", strerror(errno));</span><br><span>                 return NULL;</span><br><span>@@ -83,7 +89,7 @@</span><br><span>             return NULL;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   srv = ast_calloc(1, sizeof(*srv) + size + host_size + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+     srv = ast_calloc(1, sizeof(*srv) + size + strlen(host) + 1);</span><br><span>         if (!srv) {</span><br><span>          return NULL;</span><br><span>         }</span><br><span>@@ -94,8 +100,6 @@</span><br><span> </span><br><span>   srv->host = srv->data + size;</span><br><span>  strcpy((char *)srv->host, host); /* SAFE */</span><br><span style="color: hsl(0, 100%, 40%);">-  ((char *)srv->host)[host_size] = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    srv->generic.data_ptr = srv->data;</span><br><span> </span><br><span>         return (struct ast_dns_record *)srv;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10641">change 10641</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/10641"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 15 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I4d35d6c431c6c6836cb61d37b1378cc47f0b414d </div>
<div style="display:none"> Gerrit-Change-Number: 10641 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>