2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

2474. [bug] ACL structures could be allocated with insufficient

space, causing an array overrun. [RT #18765]
This commit is contained in:
Evan Hunt
2008-10-24 02:28:55 +00:00
parent be40453080
commit 06a230fe9f
2 changed files with 61 additions and 10 deletions

View File

@@ -1,3 +1,6 @@
2474. [bug] ACL structures could be allocated with insufficient
space, causing an array overrun. [RT #18765]
2473. [port] linux: raise the limit on open files to the possible
maximum value before spawning threads; 'files'
specified in named.conf doesn't seem to work with

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: aclconf.c,v 1.21 2008/09/01 05:36:00 marka Exp $ */
/* $Id: aclconf.c,v 1.22 2008/10/24 02:28:55 each Exp $ */
#include <config.h>
@@ -160,6 +160,51 @@ convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx,
return (dns_name_dup(dns_fixedname_name(&fixname), mctx, dnsname));
}
/*
* Recursively pre-parse an ACL definition to find the total number
* of non-IP-prefix elements (localhost, localnets, key) in all nested
* ACLs, so that the parent will have enough space allocated for the
* elements table after all the nested ACLs have been merged in to the
* parent.
*/
static int
count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx)
{
const cfg_listelt_t *elt;
const cfg_obj_t *cacl = NULL;
isc_result_t result;
int n = 0;
for (elt = cfg_list_first(caml);
elt != NULL;
elt = cfg_list_next(elt)) {
const cfg_obj_t *ce = cfg_listelt_value(elt);
/* negated element; just get the value. */
if (cfg_obj_istuple(ce))
ce = cfg_tuple_get(ce, "value");
if (cfg_obj_istype(ce, &cfg_type_keyref)) {
n++;
} else if (cfg_obj_islist(ce)) {
n += count_acl_elements(ce, cctx);
} else if (cfg_obj_isstring(ce)) {
const char *name = cfg_obj_asstring(ce);
if (strcasecmp(name, "localhost") == 0 ||
strcasecmp(name, "localnets") == 0) {
n++;
} else if (strcasecmp(name, "any") != 0 &&
strcasecmp(name, "none") != 0) {
result = get_acl_def(cctx, name, &cacl);
if (result == ISC_R_SUCCESS)
n += count_acl_elements(cacl, cctx) + 1;
}
}
}
return n;
}
isc_result_t
cfg_acl_fromconfig(const cfg_obj_t *caml,
const cfg_obj_t *cctx,
@@ -194,14 +239,18 @@ cfg_acl_fromconfig(const cfg_obj_t *caml,
} else {
/*
* Need to allocate a new ACL structure. Count the items
* in the ACL definition and allocate space for that many
* elements (even though some or all of them may end up in
* the iptable instead of the element array).
* in the ACL definition that will require space in the
* elemnts table. (Note that if nest_level is nonzero,
* *everything* goes in the elements table.)
*/
isc_boolean_t recurse = ISC_TF(nest_level == 0);
result = dns_acl_create(mctx,
cfg_list_length(caml, recurse),
&dacl);
int nelem;
if (nest_level == 0)
nelem = count_acl_elements(caml, cctx);
else
nelem = cfg_list_length(caml, ISC_FALSE);
result = dns_acl_create(mctx, nelem, &dacl);
if (result != ISC_R_SUCCESS)
return (result);
}
@@ -209,8 +258,7 @@ cfg_acl_fromconfig(const cfg_obj_t *caml,
de = dacl->elements;
for (elt = cfg_list_first(caml);
elt != NULL;
elt = cfg_list_next(elt))
{
elt = cfg_list_next(elt)) {
const cfg_obj_t *ce = cfg_listelt_value(elt);
isc_boolean_t neg;