Fix a buffer handling bug when adding lots of registry keys
authorVolker Lendecke <vl@samba.org>
Thu, 19 Feb 2009 13:16:44 +0000 (14:16 +0100)
committerKarolin Seeger <kseeger@samba.org>
Fri, 27 Mar 2009 12:06:48 +0000 (13:06 +0100)
This is *ancient*... From 2002, and nobody noticed until someone added lots of
shares using net conf... :-)
(cherry picked from commit 36ae846d15027df5e3a02ffabb08183dad9f6517)

source/registry/reg_backend_db.c

index 52a01507c09b3b4987008d2187ffbd102ded2cdc..12ccc16e639d3a9bbf1fcbf507f6c75fd7513886 100644 (file)
@@ -487,21 +487,36 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
        /* pack all the strings */
 
        for (i=0; i<num_subkeys; i++) {
-               len += tdb_pack(buffer+len, buflen-len, "f",
-                               regsubkey_ctr_specific_key(ctr, i));
-               if (len > buflen) {
-                       /* allocate some extra space */
-                       buffer = (uint8 *)SMB_REALLOC(buffer, len*2);
+               size_t thistime;
+
+               thistime = tdb_pack(buffer+len, buflen-len, "f",
+                                   regsubkey_ctr_specific_key(ctr, i));
+               if (len+thistime > buflen) {
+                       size_t thistime2;
+                       /*
+                        * tdb_pack hasn't done anything because of the short
+                        * buffer, allocate extra space.
+                        */
+                       buffer = SMB_REALLOC_ARRAY(buffer, uint8_t,
+                                                  (len+thistime)*2);
                        if(buffer == NULL) {
                                DEBUG(0, ("regdb_store_keys: Failed to realloc "
-                                         "memory of size [%d]\n", len*2));
+                                         "memory of size [%d]\n",
+                                         (len+thistime)*2));
+                               ret = false;
+                               goto done;
+                       }
+                       buflen = (len+thistime)*2;
+                       thistime2 = tdb_pack(
+                               buffer+len, buflen-len, "f",
+                               regsubkey_ctr_specific_key(ctr, i));
+                       if (thistime2 != thistime) {
+                               DEBUG(0, ("tdb_pack failed\n"));
                                ret = false;
                                goto done;
                        }
-                       buflen = len*2;
-                       len = tdb_pack(buffer+len, buflen-len, "f",
-                                      regsubkey_ctr_specific_key(ctr, i));
                }
+               len += thistime;
        }
 
        /* finally write out the data */