comparison src/core/ngx_resolver.c @ 4619:3171ec7d0d05

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.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 14 May 2012 09:13:45 +0000
parents 778d2cc03e22
children bc5f881323b8
comparison
equal deleted inserted replaced
4618:c05cfc46b3bc 4619:3171ec7d0d05
511 511
512 ngx_queue_remove(&rn->queue); 512 ngx_queue_remove(&rn->queue);
513 513
514 /* lock alloc mutex */ 514 /* lock alloc mutex */
515 515
516 ngx_resolver_free_locked(r, rn->query); 516 if (rn->query) {
517 rn->query = NULL; 517 ngx_resolver_free_locked(r, rn->query);
518 rn->query = NULL;
519 }
518 520
519 if (rn->cnlen) { 521 if (rn->cnlen) {
520 ngx_resolver_free_locked(r, rn->u.cname); 522 ngx_resolver_free_locked(r, rn->u.cname);
521 } 523 }
522 524
1407 1409
1408 if (naddrs > 1) { 1410 if (naddrs > 1) {
1409 ngx_resolver_free(r, addrs); 1411 ngx_resolver_free(r, addrs);
1410 } 1412 }
1411 1413
1414 ngx_resolver_free(r, rn->query);
1415 rn->query = NULL;
1416
1412 return; 1417 return;
1413 1418
1414 } else if (cname) { 1419 } else if (cname) {
1415 1420
1416 /* CNAME only */ 1421 /* CNAME only */
1438 if (ctx) { 1443 if (ctx) {
1439 ctx->name = name; 1444 ctx->name = name;
1440 1445
1441 (void) ngx_resolve_name_locked(r, ctx); 1446 (void) ngx_resolve_name_locked(r, ctx);
1442 } 1447 }
1448
1449 ngx_resolver_free(r, rn->query);
1450 rn->query = NULL;
1443 1451
1444 return; 1452 return;
1445 } 1453 }
1446 1454
1447 ngx_log_error(r->log_level, r->log, 0, 1455 ngx_log_error(r->log_level, r->log, 0,