]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2722. [bug] Ensure that the memory associated with the name of
authorMark Andrews <marka@isc.org>
Tue, 20 Oct 2009 05:06:29 +0000 (05:06 +0000)
committerMark Andrews <marka@isc.org>
Tue, 20 Oct 2009 05:06:29 +0000 (05:06 +0000)
                        a node in a rbt tree is not altered during the life
                        of the node. [RT #20431]

CHANGES
lib/dns/include/dns/rbt.h
lib/dns/rbt.c

diff --git a/CHANGES b/CHANGES
index 78104b93d6abdfe1be6f0c553660af3c525d4750..7ce73e794fca46f2de69e6edbb7067c21a15b986 100644 (file)
--- 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]
 
index e9e6c4dd2dcd34ec1e6bf67f331011eaa815f0ac..27489b010196207d642024960776675c73af11d2 100644 (file)
@@ -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
index 155e253f9aa023c8baf3bf30242cdcc1b6019b51..5b50c05908028f46a1bc28215ffa4866d470b2df 100644 (file)
@@ -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.
+ *
+ *     <name_data>{1..255}<oldoffsetlen>{1}<offsets>{1..128}
+ *
+ * <name_data> contains the name of the node when it was created.
+ * <oldoffsetlen> contains the length of <offsets> when the node was created.
+ * <offsets> 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);