recopy a string being built into a tainted allocation if it meets a %s for a
tainted argument. Any intermediate-layer function that (can) return a new
allocation should behave this way; returning a tainted result if any tainted
- content is used. Users of functions that modify existing allocations should
- check if a tainted source and an untainted destination is used, and fail instead
- (sprintf() being the classic case).
+ content is used. Intermediate-layer functions (eg. Ustrncpy) that modify
+ existing allocations fail if tainted data is written into an untainted area.
+ Users of functions that modify existing allocations should check if a tainted
+ source and an untainted destination is used, and fail instead (sprintf() being
+ the classic case).
*/
static void *next_yield[NPOOLS];
static int yield_length[NPOOLS] = { -1, -1, -1, -1, -1, -1 };
-/* The limits of the tainted pools. Tracking these on new allocations enables
-a fast is_tainted implementation. We assume the kernel only allocates mmaps using
-one side or the other of data+heap, not both. */
-
-void * tainted_base = (void *)-1;
-void * tainted_top = (void *)0;
-
/* pool_malloc holds the amount of memory used by the store pools; this goes up
and down as store is reset or released. nonpool_malloc is the total got by
malloc from other calls; this doesn't go down because it is just freed by
/******************************************************************************/
-#ifndef TAINT_CHECK_FAST
/* Test if a pointer refers to tainted memory.
Slower version check, for use when platform intermixes malloc and mmap area
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]))
{
- char * bc = CS b + ALIGNED_SIZEOF_STOREBLOCK;
- if (CS p >= bc && CS p <= bc + b->length) return TRUE;
+ 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)
{
- char * bc = CS b + ALIGNED_SIZEOF_STOREBLOCK;
- if (CS p >= bc && CS p <= bc + b->length) return TRUE;
+ uschar * bc = US b + ALIGNED_SIZEOF_STOREBLOCK;
+ if (US p >= bc && US p <= bc + b->length) return TRUE;
}
return FALSE;
}
-#endif
void
}
+
/*************************************************
* Get a block from the current pool *
*************************************************/
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
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to mmap %d bytes of memory: "
"called from line %d of %s", size, line, func);
-if (yield < tainted_base) tainted_base = yield;
-if ((top = US yield + size) > tainted_top) tainted_top = top;
-
return store_alloc_tail(yield, size, func, line, US"Mmap");
}