Track tainted data and refuse to expand it
[users/jgh/exim.git] / src / src / lookups / cdb.c
index 3a9078a4ecd711947c15e7cd048d5b5f5901060e..5cae1535f5efb26975dbef8ca4936d7b0d33841a 100644 (file)
@@ -43,7 +43,7 @@
  * cdb.[ch] it does *not* link against an external cdb library.
  *
  *
- * There are 2 varients included within this code.  One uses MMAP and
+ * There are 2 variants included within this code.  One uses MMAP and
  * should give better performance especially for multiple lookups on a
  * modern machine.  The other is the default implementation which is
  * used in the case where the MMAP fails or if MMAP was not compiled
@@ -131,7 +131,7 @@ cdb_bread(int fd,
 
 /*
  * cdb_bread()
- * Internal function to parse 4 byte number (endian independant) */
+ * Internal function to parse 4 byte number (endian independent) */
 
 static uint32
 cdb_unpack(uschar *buf)
@@ -184,7 +184,7 @@ cdb_open(uschar *filename,
   }
 
   /* Having got a file open we need the structure to put things in */
-  cdbp = store_get(sizeof(struct cdb_state));
+  cdbp = store_get(sizeof(struct cdb_state), FALSE);
   /* store_get() does not return if memory was not available... */
   /* preload the structure.... */
   cdbp->fileno = fileno;
@@ -210,20 +210,19 @@ cdb_open(uschar *filename,
 
     /* Now return the state struct */
     return(cdbp);
-  } else {
+  } else
     /* If we got here the map failed.  Basically we can ignore
      * this since we fall back to slower methods....
      * However lets debug log it...
      */
-    DEBUG(D_lookup) debug_printf("cdb mmap failed - %d\n", errno);
-  }
+    DEBUG(D_lookup) debug_printf_indent("cdb mmap failed - %d\n", errno);
 #endif /* HAVE_MMAP */
 
   /* In this case we have either not got MMAP allowed, or it failed */
 
   /* get a buffer to stash the basic offsets in - this should speed
    * things up a lot - especially on multiple lookups */
-  cdbp->cdb_offsets = store_get(CDB_HASH_TABLE);
+  cdbp->cdb_offsets = store_get(CDB_HASH_TABLE, FALSE);
 
   /* now fill the buffer up... */
   if (cdb_bread(fileno, cdbp->cdb_offsets, CDB_HASH_TABLE) == -1) {
@@ -293,7 +292,6 @@ hash_offset_entry,
 hash_offset,
 hash_offlen,
 hash_slotnm;
-int loop;
 
 /* Keep picky compilers happy */
 do_cache = do_cache;
@@ -319,7 +317,7 @@ if ((hash_offset + (hash_offlen * CDB_HASH_ENTRY)) > cdbp->filelen)
   {
   *errmsg = string_sprintf("cdb: corrupt cdb file %s (too short)",
                      filename);
-  DEBUG(D_lookup) debug_printf("%s\n", *errmsg);
+  DEBUG(D_lookup) debug_printf_indent("%s\n", *errmsg);
   return DEFER;
   }
 
@@ -335,7 +333,7 @@ if (cdbp->cdb_map != NULL)
   uschar * cur_pos = cur_offset + cdbp->cdb_map;
   uschar * end_pos = end_offset + cdbp->cdb_map;
 
-  for (loop = 0; (loop < hash_offlen); ++loop)
+  for (int loop = 0; (loop < hash_offlen); ++loop)
     {
     item_hash = cdb_unpack(cur_pos);
     cur_pos += 4;
@@ -367,9 +365,10 @@ if (cdbp->cdb_map != NULL)
 
           item_ptr += item_key_len;
 
-          /* ... and the returned result */
+          /* ... and the returned result.  Assume it is not
+          tainted, lacking any way of telling.  */
 
-          *result = store_get(item_dat_len + 1);
+          *result = store_get(item_dat_len + 1, FALSE);
           memcpy(*result, item_ptr, item_dat_len);
           (*result)[item_dat_len] = 0;
           return OK;
@@ -386,12 +385,12 @@ if (cdbp->cdb_map != NULL)
 
 #endif /* HAVE_MMAP */
 
-for (loop = 0; (loop < hash_offlen); ++loop)
+for (int loop = 0; (loop < hash_offlen); ++loop)
   {
   uschar packbuf[8];
 
-  if (lseek(cdbp->fileno, (off_t) cur_offset,SEEK_SET) == -1) return DEFER;
-  if (cdb_bread(cdbp->fileno, packbuf,8) == -1) return DEFER;
+  if (lseek(cdbp->fileno, (off_t) cur_offset, SEEK_SET) == -1) return DEFER;
+  if (cdb_bread(cdbp->fileno, packbuf, 8) == -1) return DEFER;
 
   item_hash = cdb_unpack(packbuf);
   item_posn = cdb_unpack(packbuf + 4);
@@ -412,31 +411,32 @@ for (loop = 0; (loop < hash_offlen); ++loop)
 
     if (item_key_len == key_len)
       {                                        /* finally check if key matches */
-      uschar * item_key = store_get(key_len);
+      rmark reset_point = store_mark();
+      uschar * item_key = store_get(key_len, TRUE); /* keys liable to be tainted */
 
       if (cdb_bread(cdbp->fileno, item_key, key_len) == -1) return DEFER;
-      if (Ustrncmp(keystring, item_key, key_len) == 0) {
-
-       /* Reclaim some store */
-       store_reset(item_key);
-
-       /* matches - get data length */
-       item_dat_len = cdb_unpack(packbuf + 4);
-
-       /* then we build a new result string.  We know we have enough
-       memory so disable Coverity errors about the tainted item_dat_ken */
-
-       *result = store_get(item_dat_len + 1);
-       /* coverity[tainted_data] */
-       if (cdb_bread(cdbp->fileno, *result, item_dat_len) == -1)
-        return DEFER;
-
-       /* coverity[tainted_data] */
-       (*result)[item_dat_len] = 0;
-       return OK;
-      }
+      if (Ustrncmp(keystring, item_key, key_len) == 0)
+        {
+        /* Reclaim some store */
+        store_reset(reset_point);
+
+        /* matches - get data length */
+        item_dat_len = cdb_unpack(packbuf + 4);
+
+        /* then we build a new result string.  We know we have enough
+        memory so disable Coverity errors about the tainted item_dat_ken */
+
+        *result = store_get(item_dat_len + 1, FALSE);
+        /* coverity[tainted_data] */
+        if (cdb_bread(cdbp->fileno, *result, item_dat_len) == -1)
+         return DEFER;
+
+        /* coverity[tainted_data] */
+        (*result)[item_dat_len] = 0;
+        return OK;
+        }
       /* Reclaim some store */
-      store_reset(item_key);
+      store_reset(reset_point);
       }
     }
   cur_offset += 8;
@@ -462,14 +462,15 @@ cdb_close(void *handle)
 struct cdb_state * cdbp = handle;
 
 #ifdef HAVE_MMAP
- if (cdbp->cdb_map) {
-   munmap(CS cdbp->cdb_map, cdbp->filelen);
-   if (cdbp->cdb_map == cdbp->cdb_offsets)
+if (cdbp->cdb_map)
+  {
+  munmap(CS cdbp->cdb_map, cdbp->filelen);
+  if (cdbp->cdb_map == cdbp->cdb_offsets)
      cdbp->cdb_offsets = NULL;
- }
 }
 #endif /* HAVE_MMAP */
 
- (void)close(cdbp->fileno);
+(void)close(cdbp->fileno);
 }