Fix taint hybrid-checking on BSD
authorJeremy Harris <jgh146exb@wizmail.org>
Thu, 16 Jan 2020 22:51:53 +0000 (22:51 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Thu, 16 Jan 2020 23:34:18 +0000 (23:34 +0000)
src/src/functions.h
src/src/store.c

index 2a2c0dbb8f9fa5bc799253394f525f0c450712e2..57314a677fb486b5ef0bc0a3783de08f7b227752 100644 (file)
@@ -720,11 +720,14 @@ return ss;
        string_copy_taint_trc((s), tainted, __FUNCTION__, __LINE__)
 
 static inline uschar *
        string_copy_taint_trc((s), tainted, __FUNCTION__, __LINE__)
 
 static inline uschar *
-string_copy(const uschar * s)
+string_copy_trc(const uschar * s, const char * func, int line)
 {
 {
-return string_copy_taint((s), is_tainted(s));
+return string_copy_taint_trc((s), is_tainted(s), func, line);
 }
 
 }
 
+#define string_copy(s) \
+       string_copy_trc((s), __FUNCTION__, __LINE__)
+
 
 /*************************************************
 *       Copy, lowercase and save string          *
 
 /*************************************************
 *       Copy, lowercase and save string          *
index aceb0e5d66789d50f128698e3b0178407de75343..1fe97e6c9897f0ef7116561da1d483cb3e39fa2f 100644 (file)
@@ -199,16 +199,15 @@ BOOL
 is_tainted_fn(const void * p)
 {
 storeblock * b;
 is_tainted_fn(const void * p)
 {
 storeblock * b;
-int pool;
 
 
-for (pool = POOL_TAINT_BASE; pool < nelem(chainbase); pool++)
+for (int pool = POOL_TAINT_BASE; pool < nelem(chainbase); pool++)
   if ((b = current_block[pool]))
     {
     uschar * bc = US b + ALIGNED_SIZEOF_STOREBLOCK;
     if (US p >= bc && US p <= bc + b->length) return TRUE;
     }
 
   if ((b = current_block[pool]))
     {
     uschar * bc = US b + ALIGNED_SIZEOF_STOREBLOCK;
     if (US p >= bc && US p <= bc + b->length) return TRUE;
     }
 
-for (pool = POOL_TAINT_BASE; pool < nelem(chainbase); pool++)
+for (int pool = POOL_TAINT_BASE; pool < nelem(chainbase); pool++)
   for (b = chainbase[pool]; b; b = b->next)
     {
     uschar * bc = US b + ALIGNED_SIZEOF_STOREBLOCK;
   for (b = chainbase[pool]; b; b = b->next)
     {
     uschar * bc = US b + ALIGNED_SIZEOF_STOREBLOCK;
@@ -228,10 +227,28 @@ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Taint mismatch, %s: %s %d\n",
 static void
 use_slow_taint_check(void)
 {
 static void
 use_slow_taint_check(void)
 {
+#ifndef COMPILE_UTILITY
 DEBUG(D_any) debug_printf("switching to slow-mode taint checking\n");
 DEBUG(D_any) debug_printf("switching to slow-mode taint checking\n");
+#endif
 f.taint_check_slow = TRUE;
 }
 
 f.taint_check_slow = TRUE;
 }
 
+static void
+verify_all_untainted(void)
+{
+for (int pool = 0; pool < POOL_TAINT_BASE; pool++)
+  for (storeblock * b = chainbase[pool]; b; b = b->next)
+    {
+    uschar * bc = US b + ALIGNED_SIZEOF_STOREBLOCK;
+    if (is_tainted(bc))
+      {
+      use_slow_taint_check();
+      return;
+      }
+    }
+}
+
+
 
 /*************************************************
 *       Get a block from the current pool        *
 
 /*************************************************
 *       Get a block from the current pool        *
@@ -765,7 +782,7 @@ int pool = tainted ? store_pool + POOL_TAINT_BASE : store_pool;
 BOOL release_ok = !tainted && store_last_get[pool] == block;
 uschar * newtext;
 
 BOOL release_ok = !tainted && store_last_get[pool] == block;
 uschar * newtext;
 
-#ifndef MACRO_PREDEF
+#if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
 if (is_tainted(block) != tainted)
   die_tainted(US"store_newblock", CUS func, linenumber);
 #endif
 if (is_tainted(block) != tainted)
   die_tainted(US"store_newblock", CUS func, linenumber);
 #endif
@@ -824,6 +841,7 @@ if (!(yield = mmap(NULL, (size_t)size,
 
 if (yield < tainted_base) tainted_base = yield;
 if ((top = US yield + size) > tainted_top) tainted_top = top;
 
 if (yield < tainted_base) tainted_base = yield;
 if ((top = US yield + size) > tainted_top) tainted_top = top;
+if (!f.taint_check_slow) use_slow_taint_check();
 
 return store_alloc_tail(yield, size, func, line, US"Mmap");
 }
 
 return store_alloc_tail(yield, size, func, line, US"Mmap");
 }