summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2012-05-14 09:13:45 +0000
committerMaxim Dounin <mdounin@mdounin.ru>2012-05-14 09:13:45 +0000
commit7d863c0181064b08fa6b3816522551084fd91af5 (patch)
tree894636d6ad982e90eb061e8b3c62a905f1a7d70e
parent0e3b423dc6c6653d600f4bf1687f0653be04a830 (diff)
downloadnginx-7d863c0181064b08fa6b3816522551084fd91af5.tar.gz
nginx-7d863c0181064b08fa6b3816522551084fd91af5.tar.bz2
Resolver: protection from duplicate responses.
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.
Diffstat (limited to '')
-rw-r--r--src/core/ngx_resolver.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index ecf97d7f7..edc43dce2 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -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;
}