X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fstore.c;h=61f9464af58bdd76b42d07529a05cce8bc78001c;hb=aa81ee147537e2b6c2affb90749fb35cfc996396;hp=a06e1c19afd1035a804d005cf0b9ff7142d0b562;hpb=6d95688d6a272297a6a47f2fd2695cc8e5b8b730;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/store.c b/src/src/store.c index a06e1c19a..61f9464af 100644 --- a/src/src/store.c +++ b/src/src/store.c @@ -41,8 +41,32 @@ The following different types of store are recognized: and tainted. The latter is used for values derived from untrusted input, and the string-expansion mechanism refuses to operate on such values (obviously, it can expand an untainted value to return a tainted result). The classes - are implemented by duplicating the three pool types. Pool resets are requested + are implemented by duplicating the three pool types. Pool resets are requested against the nontainted sibling and apply to both siblings. + + Only memory blocks requested for tainted use are regarded as tainted; anything + else (including stack auto variables) is untainted. Care is needed when coding + to not copy untrusted data into untainted memory, as downstream taint-checks + would be avoided. + + Internally we currently use malloc for nontainted pools, and mmap for tainted + pools. The disparity is for speed of testing the taintedness of pointers; + because Linux appears to use distinct non-overlapping address allocations for + mmap vs. everything else, which means only two pointer-compares suffice for the + test. Other OS' cannot use that optimisation, and a more lengthy test against + the limits of tainted-pool allcations has to be done. + + Intermediate layers (eg. the string functions) can test for taint, and use this + for ensurinng that results have proper state. For example the + string_vformat_trc() routing supporting the string_sprintf() interface will + 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. 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). */ @@ -162,8 +186,15 @@ static void internal_tainted_free(storeblock *, const char *, int linenumber); /******************************************************************************/ -/* Slower version check, for use when platform intermixes malloc and mmap area -addresses. */ +#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) @@ -171,24 +202,22 @@ is_tainted_fn(const void * p) storeblock * b; int pool; -for (pool = 0; pool < nelem(chainbase); 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) goto hit; + if (CS p >= bc && CS p <= bc + b->length) return TRUE; } -for (pool = 0; pool < nelem(chainbase); pool++) +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) goto hit; + if (CS p >= bc && CS p <= bc + b->length) return TRUE; } return FALSE; - -hit: -return pool >= POOL_TAINT_BASE; } +#endif void @@ -209,7 +238,8 @@ block, getting a new one if necessary. The address is saved in store_last_was_get. Arguments: - size amount wanted + size amount wanted, bytes + tainted class: set to true for untrusted data (eg. from smtp input) func function from which called linenumber line number in source file