I know that almost no one uses emutls, but I was fiddling with it recently, and found a buffer overflow; the emutls_destroy() function moves past the end of an array. Patch attached.
The correctness of the fix may not be immediately obvious, but a careful study of emutls_alloc() will show that there is some off-by-one tomfoolery, coded in on purpose (personally, I think its poor/bad coding style). The corresponding tomfoolery wasn't done in the matching free code, leading to this bug. --- gcc/emutls.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) Index: gcc-4.4/gcc/emutls.c =================================================================== --- gcc-4.4.orig/gcc/emutls.c 2010-12-13 16:53:48.000000000 -0600 +++ gcc-4.4/gcc/emutls.c 2010-12-13 17:12:27.000000000 -0600 @@ -76,7 +76,11 @@ emutls_destroy (void *ptr) pointer size = arr->size; pointer i; - for (i = 0; i < size; ++i) + /* arr->size is the total size of area that 'arr' is pointing to. + * The size of 'arr->data' is one less than that. + * Properly, its (&arr->data[0]-arr)/sizeof(void *) = 1 less. + */ + for (i = 0; i < size-1; ++i) { if (arr->data[i]) free (arr->data[i][-1]);