]> git.kaiwu.me - nginx.git/commitdiff
Resolver: protection from duplicate responses.
authorMaxim Dounin <mdounin@mdounin.ru>
Mon, 14 May 2012 09:13:45 +0000 (09:13 +0000)
committerMaxim Dounin <mdounin@mdounin.ru>
Mon, 14 May 2012 09:13:45 +0000 (09:13 +0000)
If we already had CNAME in resolver node (i.e. rn->cnlen and rn->u.cname
set), and got additional response with A record, it resulted in rn->cnlen
set and rn->u.cname overwritten by rn->u.addr (or rn->u.addrs), causing
segmentation fault later in ngx_resolver_free_node() on an attempt to free
overwritten rn->u.cname.  The opposite (i.e. CNAME got after A) might cause
similar problems as well.

src/core/ngx_resolver.c

index ecf97d7f76393ccf2f22cfbd92151688841a1bcc..edc43dce21992da37188a1ed6cdea6561a60b30c 100644 (file)
@@ -513,8 +513,10 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
 
         /* lock alloc mutex */
 
-        ngx_resolver_free_locked(r, rn->query);
-        rn->query = NULL;
+        if (rn->query) {
+            ngx_resolver_free_locked(r, rn->query);
+            rn->query = NULL;
+        }
 
         if (rn->cnlen) {
             ngx_resolver_free_locked(r, rn->u.cname);
@@ -1409,6 +1411,9 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
             ngx_resolver_free(r, addrs);
         }
 
+        ngx_resolver_free(r, rn->query);
+        rn->query = NULL;
+
         return;
 
     } else if (cname) {
@@ -1441,6 +1446,9 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
             (void) ngx_resolve_name_locked(r, ctx);
         }
 
+        ngx_resolver_free(r, rn->query);
+        rn->query = NULL;
+
         return;
     }