+/* These are purely for stats-gathering */
+
+static int nbytes[NPOOLS]; /* current bytes allocated */
+static int maxbytes[NPOOLS]; /* max number reached */
+static int nblocks[NPOOLS]; /* current number of blocks allocated */
+static int maxblocks[NPOOLS];
+static int n_nonpool_blocks; /* current number of direct store_malloc() blocks */
+static int max_nonpool_blocks;
+static int max_pool_malloc; /* max value for pool_malloc */
+static int max_nonpool_malloc; /* max value for nonpool_malloc */
+
+
+#ifndef COMPILE_UTILITY
+static const uschar * pooluse[NPOOLS] = {
+[POOL_MAIN] = US"main",
+[POOL_PERM] = US"perm",
+[POOL_SEARCH] = US"search",
+[POOL_TAINT_MAIN] = US"main",
+[POOL_TAINT_PERM] = US"perm",
+[POOL_TAINT_SEARCH] = US"search",
+};
+static const uschar * poolclass[NPOOLS] = {
+[POOL_MAIN] = US"untainted",
+[POOL_PERM] = US"untainted",
+[POOL_SEARCH] = US"untainted",
+[POOL_TAINT_MAIN] = US"tainted",
+[POOL_TAINT_PERM] = US"tainted",
+[POOL_TAINT_SEARCH] = US"tainted",
+};
+#endif
+
+
+static void * store_mmap(int, const char *, int);
+static void * internal_store_malloc(int, const char *, int);
+static void internal_untainted_free(void *, const char *, int linenumber);
+static void internal_tainted_free(storeblock *, const char *, int linenumber);
+
+/******************************************************************************/
+
+#ifndef TAINT_CHECK_FAST
+/* Test if a pointer refers to tainted memory.
+
+Slower version check, for use when platform intermixes malloc and mmap area
+addresses. Test against the current-block of all tainted pools first, then all
+blocks of all tainted pools.
+
+Return: TRUE iff tainted
+*/
+
+BOOL
+is_tainted_fn(const void * p)
+{
+storeblock * b;
+int pool;
+
+for (pool = POOL_TAINT_BASE; pool < nelem(chainbase); pool++)
+ if ((b = current_block[pool]))
+ {
+ char * bc = CS b + ALIGNED_SIZEOF_STOREBLOCK;
+ if (CS p >= bc && CS p <= bc + b->length) return TRUE;
+ }
+
+for (pool = POOL_TAINT_BASE; pool < nelem(chainbase); pool++)
+ for (b = chainbase[pool]; b; b = b->next)
+ {
+ char * bc = CS b + ALIGNED_SIZEOF_STOREBLOCK;
+ if (CS p >= bc && CS p <= bc + b->length) return TRUE;
+ }
+return FALSE;
+}
+#endif
+
+
+void
+die_tainted(const uschar * msg, const uschar * func, int line)
+{
+log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Taint mismatch, %s: %s %d\n",
+ msg, func, line);
+}