diff options
| author | Maxim Dounin <mdounin@mdounin.ru> | 2012-06-04 10:15:55 +0000 |
|---|---|---|
| committer | Maxim Dounin <mdounin@mdounin.ru> | 2012-06-04 10:15:55 +0000 |
| commit | 5f291006a65d7a7dbcfbb5d315f04eaf3917d868 (patch) | |
| tree | 92cb65aa67c1436b77f9cb516b4aac12b7d24f51 | |
| parent | d9a65e9874028c9a38dde1ea52ba744ec2a19d6d (diff) | |
| download | nginx-5f291006a65d7a7dbcfbb5d315f04eaf3917d868.tar.gz nginx-5f291006a65d7a7dbcfbb5d315f04eaf3917d868.tar.bz2 | |
Merge of r4611, r4620: resolver fixes.
*) Fixed segmentation fault in ngx_resolver_create_name_query().
If name passed for resolution was { 0, NULL } (e.g. as a result
of name server returning CNAME pointing to ".") pointer wrapped
to (void *) -1 resulting in segmentation fault on an attempt to
dereference it.
Reported by Lanshun Zhou.
*) 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.
| -rw-r--r-- | src/core/ngx_resolver.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c index 02c484da6..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; } @@ -1834,6 +1842,10 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx) p--; *p-- = '\0'; + if (ctx->name.len == 0) { + return NGX_DECLINED; + } + for (s = ctx->name.data + ctx->name.len - 1; s >= ctx->name.data; s--) { if (*s != '.') { *p = *s; |
