[nginx] Resolver: fixes in A processing.

Ruslan Ermilov ru at nginx.com
Fri Dec 13 16:54:40 UTC 2013


details:   http://hg.nginx.org/nginx/rev/9c96782d9d05
branches:  
changeset: 5471:9c96782d9d05
user:      Ruslan Ermilov <ru at nginx.com>
date:      Fri Dec 06 14:30:27 2013 +0400
description:
Resolver: fixes in A processing.

Verify that class of RR is "IN".
Verify that RR data length is exactly four octets.
Correctly shift to the next RR if RR type is unknown.

diffstat:

 src/core/ngx_resolver.c |  41 ++++++++++++++++++++++++++---------------
 1 files changed, 26 insertions(+), 15 deletions(-)

diffs (142 lines):

diff -r aebdca7e8f8f -r 9c96782d9d05 src/core/ngx_resolver.c
--- a/src/core/ngx_resolver.c	Fri Dec 06 14:30:27 2013 +0400
+++ b/src/core/ngx_resolver.c	Fri Dec 06 14:30:27 2013 +0400
@@ -1179,7 +1179,7 @@ ngx_resolver_process_a(ngx_resolver_t *r
     uint32_t              hash;
     in_addr_t             addr, *addrs;
     ngx_str_t             name;
-    ngx_uint_t            type, qident, naddrs, a, i, n, start;
+    ngx_uint_t            type, class, qident, naddrs, a, i, n, start;
     ngx_resolver_an_t    *an;
     ngx_resolver_ctx_t   *ctx, *next;
     ngx_resolver_node_t  *rn;
@@ -1202,6 +1202,7 @@ ngx_resolver_process_a(ngx_resolver_t *r
     if (rn == NULL || rn->query == NULL) {
         ngx_log_error(r->log_level, r->log, 0,
                       "unexpected response for %V", &name);
+        ngx_resolver_free(r, name.data);
         goto failed;
     }
 
@@ -1211,6 +1212,7 @@ ngx_resolver_process_a(ngx_resolver_t *r
         ngx_log_error(r->log_level, r->log, 0,
                       "wrong ident %ui response for %V, expect %ui",
                       ident, &name, qident);
+        ngx_resolver_free(r, name.data);
         goto failed;
     }
 
@@ -1287,21 +1289,33 @@ ngx_resolver_process_a(ngx_resolver_t *r
         an = (ngx_resolver_an_t *) &buf[i];
 
         type = (an->type_hi << 8) + an->type_lo;
+        class = (an->class_hi << 8) + an->class_lo;
         len = (an->len_hi << 8) + an->len_lo;
         ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16)
             + (an->ttl[2] << 8) + (an->ttl[3]);
 
+        if (class != 1) {
+            ngx_log_error(r->log_level, r->log, 0,
+                          "unexpected RR class %ui", class);
+            goto failed;
+        }
+
         if (ttl < 0) {
             ttl = 0;
         }
 
+        i += sizeof(ngx_resolver_an_t);
+
         switch (type) {
 
         case NGX_RESOLVE_A:
 
-            i += sizeof(ngx_resolver_an_t);
-
-            if (i + len > last) {
+            if (len != 4) {
+                err = "invalid A record in DNS response";
+                goto invalid;
+            }
+
+            if (i + 4 > last) {
                 goto short_response;
             }
 
@@ -1310,21 +1324,16 @@ ngx_resolver_process_a(ngx_resolver_t *r
 
             naddrs++;
 
-            i += len;
-
             break;
 
         case NGX_RESOLVE_CNAME:
 
-            cname = &buf[i] + sizeof(ngx_resolver_an_t);
-            i += sizeof(ngx_resolver_an_t) + len;
+            cname = &buf[i];
 
             break;
 
         case NGX_RESOLVE_DNAME:
 
-            i += sizeof(ngx_resolver_an_t) + len;
-
             break;
 
         default:
@@ -1332,6 +1341,8 @@ ngx_resolver_process_a(ngx_resolver_t *r
             ngx_log_error(r->log_level, r->log, 0,
                           "unexpected RR type %ui", type);
         }
+
+        i += len;
     }
 
     ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
@@ -1347,7 +1358,7 @@ ngx_resolver_process_a(ngx_resolver_t *r
 
             addrs = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t));
             if (addrs == NULL) {
-                return;
+                goto failed;
             }
 
             n = 0;
@@ -1395,7 +1406,7 @@ ngx_resolver_process_a(ngx_resolver_t *r
             addrs = ngx_resolver_dup(r, rn->u.addrs,
                                      naddrs * sizeof(in_addr_t));
             if (addrs == NULL) {
-                return;
+                goto failed;
             }
         }
 
@@ -1439,7 +1450,7 @@ ngx_resolver_process_a(ngx_resolver_t *r
         /* CNAME only */
 
         if (ngx_resolver_copy(r, &name, buf, cname, buf + last) != NGX_OK) {
-            return;
+            goto failed;
         }
 
         ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
@@ -1467,6 +1478,8 @@ ngx_resolver_process_a(ngx_resolver_t *r
         ngx_resolver_free(r, rn->query);
         rn->query = NULL;
 
+        /* unlock name mutex */
+
         return;
     }
 
@@ -1490,8 +1503,6 @@ failed:
 
     /* unlock name mutex */
 
-    ngx_resolver_free(r, name.data);
-
     return;
 }
 



More information about the nginx-devel mailing list