X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/f3ebb786e451da973560f1c9d8cdb151d25108b5..362e4161e252f96a7b529d52f650ddc88d1cc9f7:/src/src/store.c diff --git a/src/src/store.c b/src/src/store.c index 7871d0ccc..a06e1c19a 100644 --- a/src/src/store.c +++ b/src/src/store.c @@ -106,8 +106,8 @@ static int yield_length[NPOOLS] = { -1, -1, -1, -1, -1, -1 }; a fast is_tainted implementation. We assume the kernel only allocates mmaps using one side or the other of data+heap, not both. */ -static void * tainted_base = (void *)-1; -static void * tainted_top = (void *)0; +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 @@ -135,6 +135,7 @@ 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", @@ -151,29 +152,45 @@ static const uschar * poolclass[NPOOLS] = { [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_store_free(void *, const char *, int linenumber); +static void internal_untainted_free(void *, const char *, int linenumber); +static void internal_tainted_free(storeblock *, const char *, int linenumber); /******************************************************************************/ -/* Predicate: if an address is in a tainted pool. -By extension, a variable pointing to this address is tainted. -*/ +/* Slower version check, for use when platform intermixes malloc and mmap area +addresses. */ BOOL -is_tainted(const void * p) +is_tainted_fn(const void * p) { -BOOL rc = p >= tainted_base && p < tainted_top; +storeblock * b; +int pool; -#ifndef COMPILE_UTILITY -DEBUG(D_memory) if (rc) debug_printf_indent("is_tainted: YES\n"); -#endif -return rc; +for (pool = 0; 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) goto hit; + } + +for (pool = 0; 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) goto hit; + } +return FALSE; + +hit: +return pool >= POOL_TAINT_BASE; } + void die_tainted(const uschar * msg, const uschar * func, int line) { @@ -232,15 +249,9 @@ if (size > yield_length[pool]) /* Give up on this block, because it's too small */ nblocks[pool]--; if (pool < POOL_TAINT_BASE) - internal_store_free(newblock, func, linenumber); + internal_untainted_free(newblock, func, linenumber); else - { -#ifndef COMPILE_UTILITY - DEBUG(D_memory) - debug_printf("---Unmap %6p %-20s %4d\n", newblock, func, linenumber); -#endif - munmap(newblock, newblock->length + ALIGNED_SIZEOF_STOREBLOCK); - } + internal_tainted_free(newblock, func, linenumber); newblock = NULL; } @@ -499,15 +510,9 @@ while ((b = bb)) pool_malloc -= siz; nblocks[pool]--; if (pool < POOL_TAINT_BASE) - internal_store_free(b, func, linenumber); + internal_untainted_free(b, func, linenumber); else - { -#ifndef COMPILE_UTILITY - DEBUG(D_memory) - debug_printf("---Unmap %6p %-20s %4d\n", b, func, linenumber); -#endif - munmap(b, b->length + ALIGNED_SIZEOF_STOREBLOCK); - } + internal_tainted_free(b, func, linenumber); } /* Cut out the debugging stuff for utilities, but stop picky compilers from @@ -725,8 +730,10 @@ int pool = tainted ? store_pool + POOL_TAINT_BASE : store_pool; BOOL release_ok = !tainted && store_last_get[pool] == block; uschar * newtext; +#ifndef MACRO_PREDEF if (is_tainted(block) != tainted) die_tainted(US"store_newblock", CUS func, linenumber); +#endif newtext = store_get(newsize, tainted); memcpy(newtext, block, len); @@ -781,7 +788,7 @@ if (!(yield = mmap(NULL, (size_t)size, "called from line %d of %s", size, line, func); if (yield < tainted_base) tainted_base = yield; -if ((top = yield + size) > tainted_top) tainted_top = top; +if ((top = US yield + size) > tainted_top) tainted_top = top; return store_alloc_tail(yield, size, func, line, US"Mmap"); } @@ -840,7 +847,7 @@ Returns: nothing */ static void -internal_store_free(void *block, const char *func, int linenumber) +internal_untainted_free(void * block, const char * func, int linenumber) { #ifdef COMPILE_UTILITY func = func; @@ -853,10 +860,24 @@ free(block); } void -store_free_3(void *block, const char *func, int linenumber) +store_free_3(void * block, const char * func, int linenumber) { n_nonpool_blocks--; -internal_store_free(block, func, linenumber); +internal_untainted_free(block, func, linenumber); +} + +/******************************************************************************/ +static void +internal_tainted_free(storeblock * block, const char * func, int linenumber) +{ +#ifdef COMPILE_UTILITY +func = func; +linenumber = linenumber; +#else +DEBUG(D_memory) + debug_printf("---Unmap %6p %-20s %4d\n", block, func, linenumber); +#endif +munmap((void *)block, block->length + ALIGNED_SIZEOF_STOREBLOCK); } /******************************************************************************/