From: Mark Andrews Date: Tue, 20 Oct 2009 05:06:29 +0000 (+0000) Subject: 2722. [bug] Ensure that the memory associated with the name of X-Git-Tag: v9.5.2-P1~1^5~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=123f33f60e62fa443e022b9ad2a7259999d994e5;p=thirdparty%2Fbind9.git 2722. [bug] Ensure that the memory associated with the name of a node in a rbt tree is not altered during the life of the node. [RT #20431] --- diff --git a/CHANGES b/CHANGES index 78104b93d6a..7ce73e794fc 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +2722. [bug] Ensure that the memory associated with the name of + a node in a rbt tree is not altered during the life + of the node. [RT #20431] + 2721. [port] Have dst__entropy_status() prime the random number generator. [RT #20369] diff --git a/lib/dns/include/dns/rbt.h b/lib/dns/include/dns/rbt.h index e9e6c4dd2dc..27489b01019 100644 --- a/lib/dns/include/dns/rbt.h +++ b/lib/dns/include/dns/rbt.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbt.h,v 1.69.36.2 2009/01/19 23:47:03 tbox Exp $ */ +/* $Id: rbt.h,v 1.69.36.3 2009/10/20 05:06:29 marka Exp $ */ #ifndef DNS_RBT_H #define DNS_RBT_H 1 @@ -105,10 +105,10 @@ struct dns_rbtnode { unsigned int is_root : 1; /*%< range is 0..1 */ unsigned int color : 1; /*%< range is 0..1 */ unsigned int find_callback : 1; /*%< range is 0..1 */ - unsigned int attributes : 4; /*%< range is 0..2 */ + unsigned int attributes : 5; /*%< range is 0..2 */ unsigned int namelen : 8; /*%< range is 1..255 */ unsigned int offsetlen : 8; /*%< range is 1..128 */ - unsigned int padbytes : 9; /*%< range is 0..380 */ + unsigned int oldnamelen : 8; /*%< range is 1..255 */ /*@}*/ #ifdef DNS_RBT_USEHASH diff --git a/lib/dns/rbt.c b/lib/dns/rbt.c index 155e253f9aa..5b50c059080 100644 --- a/lib/dns/rbt.c +++ b/lib/dns/rbt.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbt.c,v 1.138.36.5 2009/01/19 23:47:02 tbox Exp $ */ +/* $Id: rbt.c,v 1.138.36.6 2009/10/20 05:06:29 marka Exp $ */ /*! \file */ @@ -85,9 +85,9 @@ struct dns_rbt { #define HASHVAL(node) ((node)->hashval) #define COLOR(node) ((node)->color) #define NAMELEN(node) ((node)->namelen) +#define OLDNAMELEN(node) ((node)->oldnamelen) #define OFFSETLEN(node) ((node)->offsetlen) #define ATTRS(node) ((node)->attributes) -#define PADBYTES(node) ((node)->padbytes) #define IS_ROOT(node) ISC_TF((node)->is_root == 1) #define FINDCALLBACK(node) ISC_TF((node)->find_callback == 1) @@ -100,13 +100,23 @@ struct dns_rbt { #define LOCKNUM(node) ((node)->locknum) /*% - * The variable length stuff stored after the node. + * The variable length stuff stored after the node has the following + * structure. + * + * {1..255}{1}{1..128} + * + * contains the name of the node when it was created. + * contains the length of when the node was created. + * contains the offets into name for each label when the node was + * created. */ + #define NAME(node) ((unsigned char *)((node) + 1)) -#define OFFSETS(node) (NAME(node) + NAMELEN(node)) +#define OFFSETS(node) (NAME(node) + OLDNAMELEN(node) + 1) +#define OLDOFFSETLEN(node) (OFFSETS(node)[-1]) #define NODE_SIZE(node) (sizeof(*node) + \ - NAMELEN(node) + OFFSETLEN(node) + PADBYTES(node)) + OLDNAMELEN(node) + OLDOFFSETLEN(node) + 1) /*% * Color management. @@ -552,11 +562,6 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) { NAMELEN(current) = prefix->length; OFFSETLEN(current) = prefix->labels; - memcpy(OFFSETS(current), prefix->offsets, - prefix->labels); - PADBYTES(current) += - (current_name.length - prefix->length) + - (current_name.labels - prefix->labels); /* * Set up the new root of the next level. @@ -1422,7 +1427,7 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) { * Allocate space for the node structure, the name, and the offsets. */ node = (dns_rbtnode_t *)isc_mem_get(mctx, sizeof(*node) + - region.length + labels); + region.length + labels + 1); if (node == NULL) return (ISC_R_NOMEMORY); @@ -1458,10 +1463,12 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) { * The offsets table could be made smaller by eliminating the * first offset, which is always 0. This requires changes to * lib/dns/name.c. + * + * Note: OLDOFFSETLEN *must* be assigned *after* OLDNAMELEN is assigned + * as it uses OLDNAMELEN. */ - NAMELEN(node) = region.length; - PADBYTES(node) = 0; - OFFSETLEN(node) = labels; + OLDNAMELEN(node) = NAMELEN(node) = region.length; + OLDOFFSETLEN(node) = OFFSETLEN(node) = labels; ATTRS(node) = name->attributes; memcpy(NAME(node), region.base, region.length);