mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 14:19:59 -04:00
prevent an infinite loop in fix_iterator()
it was possible for fix_iterator() to get stuck in a loop while trying to find the predecessor of a missing node. this has been fixed and a regression test has been added.
This commit is contained in:
parent
84f79cd164
commit
ea9a8cb392
2 changed files with 54 additions and 2 deletions
13
lib/dns/qp.c
13
lib/dns/qp.c
|
|
@ -2115,6 +2115,17 @@ fix_iterator(dns_qpreader_t *qp, dns_qpiter_t *iter, dns_qpnode_t *start,
|
|||
return (leaf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case: if the search key differs even before the root
|
||||
* key offset, it means the name desired either precedes or
|
||||
* follows the entire range of names in the database, and
|
||||
* popping up the stack won't help us, so just move the
|
||||
* iterator one step back from the origin and return.
|
||||
*/
|
||||
if (to < branch_key_offset(iter->stack[0])) {
|
||||
dns_qpiter_init(qp, iter);
|
||||
return (prevleaf(iter));
|
||||
}
|
||||
/*
|
||||
* As long as the branch offset point is after the point where the
|
||||
* search key differs, we need to branch up and find a better leaf
|
||||
|
|
@ -2128,8 +2139,6 @@ fix_iterator(dns_qpreader_t *qp, dns_qpiter_t *iter, dns_qpnode_t *start,
|
|||
* go to the parent branch and iterate back to the
|
||||
* predecessor from that point.
|
||||
*/
|
||||
iter->stack[iter->sp] = NULL;
|
||||
iter->sp--;
|
||||
n = prevleaf(iter);
|
||||
leaf = n;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -755,6 +755,48 @@ ISC_RUN_TEST_IMPL(predecessors) {
|
|||
dns_qp_destroy(&qp);
|
||||
}
|
||||
|
||||
/*
|
||||
* this is a regression test for an infinite loop that could
|
||||
* previously occur in fix_iterator()
|
||||
*/
|
||||
ISC_RUN_TEST_IMPL(fixiterator) {
|
||||
dns_qp_t *qp = NULL;
|
||||
const char insert[][32] = { "dynamic.",
|
||||
"a.dynamic.",
|
||||
"aaaa.dynamic.",
|
||||
"cdnskey.dynamic.",
|
||||
"cds.dynamic.",
|
||||
"cname.dynamic.",
|
||||
"dname.dynamic.",
|
||||
"dnskey.dynamic.",
|
||||
"ds.dynamic.",
|
||||
"mx.dynamic.",
|
||||
"ns.dynamic.",
|
||||
"nsec.dynamic.",
|
||||
"private-cdnskey.dynamic.",
|
||||
"private-dnskey.dynamic.",
|
||||
"rrsig.dynamic.",
|
||||
"txt.dynamic.",
|
||||
"" };
|
||||
int i = 0;
|
||||
|
||||
dns_qp_create(mctx, &string_methods, NULL, &qp);
|
||||
while (insert[i][0] != '\0') {
|
||||
insert_str(qp, insert[i++]);
|
||||
}
|
||||
|
||||
static struct check_predecessors check1[] = {
|
||||
{ "newtext.dynamic.", "mx.dynamic.", DNS_R_PARTIALMATCH, 6 },
|
||||
{ "absent.", "txt.dynamic.", ISC_R_NOTFOUND, 0 },
|
||||
{ "nonexistent.", "txt.dynamic.", ISC_R_NOTFOUND, 0 },
|
||||
{ NULL, NULL, 0, 0 }
|
||||
};
|
||||
|
||||
check_predecessors(qp, check1);
|
||||
|
||||
dns_qp_destroy(&qp);
|
||||
}
|
||||
|
||||
ISC_TEST_LIST_START
|
||||
ISC_TEST_ENTRY(qpkey_name)
|
||||
ISC_TEST_ENTRY(qpkey_sort)
|
||||
|
|
@ -762,6 +804,7 @@ ISC_TEST_ENTRY(qpiter)
|
|||
ISC_TEST_ENTRY(partialmatch)
|
||||
ISC_TEST_ENTRY(qpchain)
|
||||
ISC_TEST_ENTRY(predecessors)
|
||||
ISC_TEST_ENTRY(fixiterator)
|
||||
ISC_TEST_LIST_END
|
||||
|
||||
ISC_TEST_MAIN
|
||||
|
|
|
|||
Loading…
Reference in a new issue