mod_proxy_http2: thread safety with MPM prefork, still..
The allocator of pchild has no mutex with MPM prefork, but we need one
for h2 workers threads synchronization.
Even though mod_http2 shouldn't be used with prefork, better be safe than
sorry, so forcibly set the mutex in h2_child_init() if it doesn't exist.
This prevents the below situation:
AddressSanitizer: heap-use-after-free on address 0x6250003ea938 at pc 0x7fe229f40f3c bp 0x7fe22146dd30 sp 0x7fe22146dd28
WRITE of size 8 at 0x6250003ea938 thread T4
#0 0x7fe229f40f3b in apr_pool_destroy memory/unix/apr_pools.c:1015
`-> if ((*pool->ref = pool->sibling) != NULL)
#1 0x7fe229f6ef1a in apr_thread_exit threadproc/unix/thread.c:206
#2 0x7fe223a26671 in slot_run /home/yle/src/apache/httpd/trunk.ro/modules/http2/h2_workers.c:248
#3 0x7fe229f6ebcc in dummy_worker threadproc/unix/thread.c:142
#4 0x7fe229ecbea6 in start_thread nptl/pthread_create.c:477
#5 0x7fe229df9d4e in __clone (/lib/x86_64-linux-gnu/libc.so.6+0xfdd4e)
0x6250003ea938 is located 56 bytes inside of 8192-byte region [0x6250003ea900,0x6250003ec900)
freed by thread T6 here:
#0 0x7fe22a1ecb6f in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xa9b6f)
#1 0x7fe229f3fe38 in allocator_free memory/unix/apr_pools.c:507
#2 0x7fe229f4107b in apr_pool_destroy memory/unix/apr_pools.c:1043
#3 0x7fe229f6ef1a in apr_thread_exit threadproc/unix/thread.c:206
#4 0x7fe223a26671 in slot_run /home/yle/src/apache/httpd/trunk.ro/modules/http2/h2_workers.c:248
#5 0x7fe229f6ebcc in dummy_worker threadproc/unix/thread.c:142
#6 0x7fe229ecbea6 in start_thread nptl/pthread_create.c:477
mod_proxy_http2: follow up to r1883704.
For event/worker MPMs, pchild uses pconf's allocator, so its is NULL.
Submitted by: ylavic
Reviewed by: ylavic, jorton, covener
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@
1885138 13f79535-47bb-0310-9956-
ffa450edef68
/* Runs once per created child process. Perform any process
* related initionalization here.
*/
-static void h2_child_init(apr_pool_t *pool, server_rec *s)
+static void h2_child_init(apr_pool_t *pchild, server_rec *s)
{
+ apr_allocator_t *allocator;
+ apr_thread_mutex_t *mutex;
+ apr_status_t status;
+
+ /* The allocator of pchild has no mutex with MPM prefork, but we need one
+ * for h2 workers threads synchronization. Even though mod_http2 shouldn't
+ * be used with prefork, better be safe than sorry, so forcibly set the
+ * mutex here. For MPM event/worker, pchild has no allocator so pconf's
+ * is used, with its mutex.
+ */
+ allocator = apr_pool_allocator_get(pchild);
+ if (allocator) {
+ mutex = apr_allocator_mutex_get(allocator);
+ if (!mutex) {
+ apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, pchild);
+ apr_allocator_mutex_set(allocator, mutex);
+ }
+ }
+
/* Set up our connection processing */
- apr_status_t status = h2_conn_child_init(pool, s);
+ status = h2_conn_child_init(pchild, s);
if (status != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, status, s,
APLOGNO(02949) "initializing connection handling");
}
-
}
/* Install this module into the apache2 infrastructure.