You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Fernando Vicente <fv...@mwneo.com> on 2016/06/16 13:46:11 UTC

apr_thread_pool_create uses memory pool in an unsafe way?

Good morning!

This is my first e-mail to this mailing list, please be patient :)

I'm using apr + apr-util in a project, and recently discovered a random
corruption on an apr_psprintf which happens after an apr_thread_pool_create.

I was able to make a small program that reproduces this issue:

int main(int argc,char *argv[],char *envp[])
{
apr_pool_t *mempool;
apr_thread_pool_t *threadpool; /**< thread pool used to process incoming
messages */

apr_initialize();
apr_pool_create(&mempool,NULL);
if(!mempool) {
printf("Error creating memory pool");
return(SE_APR_MEMPOOL);
}
/* create the thread pool */
if(apr_thread_pool_create(&threadpool,2,50,mempool) != APR_SUCCESS) {
return(1);
}
apr_thread_pool_idle_max_set(threadpool,10);
{
int k;
for(k=0; k < 200000;k++) {
const char
*x=apr_psprintf(mempool,"PATH=%s%s%s","/Users/fvicente/workspace/mwapp_cco/darwin-x86_64/bin/python/bin",":","/Users/fvicente/.rbenv/shims:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin");
if(memcmp(x, "PATH", 4)) {
printf("ERROR! [j: %d]: %s\n", k, x);
fflush(stdout);
abort();
}
}
printf("END\n");
abort();
}

Keep it running!, it will fail (eventually).

COUNTER=0 && until ./crasher |grep "ERROR" -C 999; do echo -n  $COUNTER = ;
let COUNTER=COUNTER+1; done

If I understood the problem correctly, apr_thread_pool_create creates the
initial number of threads, and passes the pool to them, and they do
something with the pool (apr_pcalloc for example). Then we have different
threads (including my apr_psprintf on the main thread) using the same pool,
which is not safe according to some other e-mail in this mailing list
<http://mail-archives.apache.org/mod_mbox/apr-dev/200401.mbox/%3C5.2.0.9.2.20040113134737.030bb260@pop3.rowe-clan.net%3E>
.

So, I've fixed my problem by creating a specific mempool only used by the
apr_thread_pool_create. However, I wonder if it won't be even better that
the thread pool function created a mempool for each thread as it seems to
be the recommended design pattern.



Thanks!
Fernando.