Corrected bad INSIST logic in isc_radix_remove()
Summary
When use isc_radix_remove, if the target node has parent and child, it will make a coredump.
BIND version used
BIND-9.9.6
Steps to reproduce
- isc_radix_create: maxbits = 32
- isc_radix_insert: "1.1.1.1/32"
- isc_radix_insert: "1.1.1.0/24"
- isc_radix_remove: "1.1.1.0/24" then there is a coredump
What is the current bug behavior?
coredump
What is the expected correct behavior?
no coredump
Relevant logs and/or screenshots
core:
#0 0x00007f9115c22387 in raise () from /usr/lib64/libc.so.6
#1 0x00007f9115c23a78 in abort () from /usr/lib64/libc.so.6
#2 0x000000000049e349 in assertion_failed (file=, line=, type=isc_assertiontype_insist,
cond=0x6c7667 "parent->l == node")
#3 0x000000000060b09a in isc_assertion_failed (file=, line=, type=)
#4 (closed) 0x00000000006237e0 in isc_radix_remove (radix=0x7f9115410cf0, node=0x7f910b00f370)
at lib/isc/radix.c:704
In lib/isc/radix.c L698-L707, after isc_mem_put, node is NULL, but parent->r or parent->l is not NULL, there is a bad INSIST logic. code:
isc_mem_put(radix->mctx, node, sizeof(*node));
radix->num_active_node--;
if (parent->r == node) {
parent->r = child;
} else {
INSIST(parent->l == node);
parent->l = child;
}
Possible fixes
use isc_mem_put after INSIST. code:
if (parent->r == node) {
parent->r = child;
} else {
INSIST(parent->l == node);
parent->l = child;
}
isc_mem_put(radix->mctx, node, sizeof(*node));
radix->num_active_node--;