2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

4816. [bug] Don't use a common array for storing EDNS options

in DiG as it could fill up. [RT #45611]
This commit is contained in:
Mark Andrews 2017-11-13 16:10:35 +11:00
parent 04934b28ea
commit 3def40b01b
2 changed files with 68 additions and 24 deletions

View File

@ -1,3 +1,6 @@
4816. [bug] Don't use a common array for storing EDNS options
in DiG as it could fill up. [RT #45611]
4815. [bug] rbt_test.c:insert_and_delete needed to call 4815. [bug] rbt_test.c:insert_and_delete needed to call
dns_rbt_addnode instead of dns_rbt_addname. [RT #46553] dns_rbt_addnode instead of dns_rbt_addname. [RT #46553]

View File

@ -655,6 +655,41 @@ make_empty_lookup(void) {
return (looknew); return (looknew);
} }
#define EDNSOPT_OPTIONS 100U
static void
cloneopts(dig_lookup_t *looknew, dig_lookup_t *lookold) {
size_t len = sizeof(looknew->ednsopts[0]) * EDNSOPT_OPTIONS;
size_t i;
looknew->ednsopts = isc_mem_allocate(mctx, len);
if (looknew->ednsopts == NULL)
fatal("out of memory");
for (i = 0; i < EDNSOPT_OPTIONS; i++) {
looknew->ednsopts[i].code = 0;
looknew->ednsopts[i].length = 0;
looknew->ednsopts[i].value = NULL;
}
looknew->ednsoptscnt = 0;
if (lookold == NULL || lookold->ednsopts == NULL)
return;
for (i = 0; i < lookold->ednsoptscnt; i++) {
len = lookold->ednsopts[i].length;
if (len != 0) {
INSIST(lookold->ednsopts[i].value != NULL);
looknew->ednsopts[i].value =
isc_mem_allocate(mctx, len);
if (looknew->ednsopts[i].value == NULL)
fatal("out of memory");
memmove(looknew->ednsopts[i].value,
lookold->ednsopts[i].value, len);
}
looknew->ednsopts[i].code = lookold->ednsopts[i].code;
looknew->ednsopts[i].length = len;
}
looknew->ednsoptscnt = lookold->ednsoptscnt;
}
/*% /*%
* Clone a lookup, perhaps copying the server list. This does not clone * Clone a lookup, perhaps copying the server list. This does not clone
* the query list, since it will be regenerated by the setup_lookup() * the query list, since it will be regenerated by the setup_lookup()
@ -700,8 +735,12 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
looknew->seenbadcookie = lookold->seenbadcookie; looknew->seenbadcookie = lookold->seenbadcookie;
looknew->badcookie = lookold->badcookie; looknew->badcookie = lookold->badcookie;
looknew->cookie = lookold->cookie; looknew->cookie = lookold->cookie;
looknew->ednsopts = lookold->ednsopts; if (lookold->ednsopts != NULL) {
looknew->ednsoptscnt = lookold->ednsoptscnt; cloneopts(looknew, lookold);
} else {
looknew->ednsopts = NULL;
looknew->ednsoptscnt = 0;
}
looknew->ednsneg = lookold->ednsneg; looknew->ednsneg = lookold->ednsneg;
looknew->padding = lookold->padding; looknew->padding = lookold->padding;
looknew->mapped = lookold->mapped; looknew->mapped = lookold->mapped;
@ -1317,13 +1356,6 @@ setup_libs(void) {
check_result(result, "isc_mutex_init"); check_result(result, "isc_mutex_init");
} }
/*
* Array of up to 100 options configured by +ednsopt
*/
#define EDNSOPT_OPTIONS 100U
static dns_ednsopt_t ednsopts[EDNSOPT_OPTIONS];
static unsigned char ednsoptscnt = 0;
typedef struct dig_ednsoptname { typedef struct dig_ednsoptname {
isc_uint32_t code; isc_uint32_t code;
const char *name; const char *name;
@ -1355,7 +1387,7 @@ save_opt(dig_lookup_t *lookup, char *code, char *value) {
isc_boolean_t found = ISC_FALSE; isc_boolean_t found = ISC_FALSE;
unsigned int i; unsigned int i;
if (ednsoptscnt == EDNSOPT_OPTIONS) if (lookup->ednsoptscnt >= EDNSOPT_OPTIONS)
fatal("too many ednsopts"); fatal("too many ednsopts");
for (i = 0; i < N_EDNS_OPTNAMES; i++) { for (i = 0; i < N_EDNS_OPTNAMES; i++) {
@ -1372,9 +1404,16 @@ save_opt(dig_lookup_t *lookup, char *code, char *value) {
fatal("bad edns code point: %s", code); fatal("bad edns code point: %s", code);
} }
ednsopts[ednsoptscnt].code = num; if (lookup->ednsopts == NULL) {
ednsopts[ednsoptscnt].length = 0; cloneopts(lookup, NULL);
ednsopts[ednsoptscnt].value = NULL; }
if (lookup->ednsopts[lookup->ednsoptscnt].value != NULL)
isc_mem_free(mctx, lookup->ednsopts[lookup->ednsoptscnt].value);
lookup->ednsopts[lookup->ednsoptscnt].code = num;
lookup->ednsopts[lookup->ednsoptscnt].length = 0;
lookup->ednsopts[lookup->ednsoptscnt].value = NULL;
if (value != NULL) { if (value != NULL) {
char *buf; char *buf;
@ -1384,14 +1423,13 @@ save_opt(dig_lookup_t *lookup, char *code, char *value) {
isc_buffer_init(&b, buf, (unsigned int) strlen(value)/2 + 1); isc_buffer_init(&b, buf, (unsigned int) strlen(value)/2 + 1);
result = isc_hex_decodestring(value, &b); result = isc_hex_decodestring(value, &b);
check_result(result, "isc_hex_decodestring"); check_result(result, "isc_hex_decodestring");
ednsopts[ednsoptscnt].value = isc_buffer_base(&b); lookup->ednsopts[lookup->ednsoptscnt].value =
ednsopts[ednsoptscnt].length = isc_buffer_usedlength(&b); isc_buffer_base(&b);
lookup->ednsopts[lookup->ednsoptscnt].length =
isc_buffer_usedlength(&b);
} }
if (lookup->ednsoptscnt == 0)
lookup->ednsopts = &ednsopts[ednsoptscnt];
lookup->ednsoptscnt++; lookup->ednsoptscnt++;
ednsoptscnt++;
} }
/*% /*%
@ -1570,6 +1608,15 @@ destroy_lookup(dig_lookup_t *lookup) {
if (lookup->ecs_addr != NULL) if (lookup->ecs_addr != NULL)
isc_mem_free(mctx, lookup->ecs_addr); isc_mem_free(mctx, lookup->ecs_addr);
if (lookup->ednsopts != NULL) {
size_t i;
for (i = 0; i < EDNSOPT_OPTIONS; i++) {
if (lookup->ednsopts[i].value != NULL)
isc_mem_free(mctx, lookup->ednsopts[i].value);
}
isc_mem_free(mctx, lookup->ednsopts);
}
isc_mem_free(mctx, lookup); isc_mem_free(mctx, lookup);
} }
@ -4127,12 +4174,6 @@ destroy_libs(void) {
debug("Removing log context"); debug("Removing log context");
isc_log_destroy(&lctx); isc_log_destroy(&lctx);
while (ednsoptscnt > 0U) {
ednsoptscnt--;
if (ednsopts[ednsoptscnt].value != NULL)
isc_mem_free(mctx, ednsopts[ednsoptscnt].value);
}
debug("Destroy memory"); debug("Destroy memory");
if (memdebugging != 0) if (memdebugging != 0)
isc_mem_stats(mctx, stderr); isc_mem_stats(mctx, stderr);