+static void * internal_store_malloc(int, const char *, int);
+static void internal_store_free(void *, const char *, int linenumber);
+
+/******************************************************************************/
+/* Initialisation, for things fragile with parameter channges when using
+static initialisers. */
+
+void
+store_init(void)
+{
+for (int i = 0; i < NPOOLS; i++)
+ {
+ yield_length[i] = -1;
+ store_block_order[i] = 12; /* log2(allocation_size) ie. 4kB */
+ }
+}
+
+/******************************************************************************/
+
+/* 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;
+
+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;
+ }
+
+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;
+ if (US p >= bc && US p < bc + b->length) return TRUE;
+ }
+return FALSE;
+}
+
+
+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);
+}
+
+
+
+/******************************************************************************/
+void
+store_writeprotect(int pool)
+{
+#if !defined(COMPILE_UTILITY) && !defined(MISSING_POSIX_MEMALIGN)
+for (storeblock * b = chainbase[pool]; b; b = b->next)
+ if (mprotect(b, ALIGNED_SIZEOF_STOREBLOCK + b->length, PROT_READ) != 0)
+ DEBUG(D_any) debug_printf("config block mprotect: (%d) %s\n", errno, strerror(errno));
+#endif
+}
+
+/******************************************************************************/