https://bz.apache.org/bugzilla/show_bug.cgi?id=60296

            Bug ID: 60296
           Summary: RMM list corruption in ldap module results in server
                    hang
           Product: Apache httpd-2
           Version: 2.4.16
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P2
         Component: mod_ldap
          Assignee: [email protected]
          Reporter: [email protected]

(I originally filed this with Debian's apache team because when I searched for
related information on this issue I turned up something in their bug tracker.
Here is the link for more context:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=814980)

The anylock structure provided by mod_ldap was set to the type
apr_anylock_none, which resulted in multiple threads mutating the shared RMM
state at the same time without any concurrency guards. The issue I was seeing
was that all the threads on the server were stuck inside the RMM internal
function find_block_of_size every 2 or 3 days, requiring the server processes
to be killed and restarted. 

We are using Apache on Windows.

I made the following patch which passes in a lock to the RMM pool created in
mod_ldap when APR_HAS_THREADS is defined. Since doing so we have not
encountered any hangs:

diff -Naur httpd-2.4.16\include\util_ldap.h httpd-2.4.16-ea\include\util_ldap.h
--- httpd-2.4.16\include\util_ldap.h    Mon Jul 14 05:07:55 2014
+++ httpd-2.4.16-ea\include\util_ldap.h    Mon Aug 29 10:20:08 2016
@@ -169,6 +169,10 @@
 #if APR_HAS_SHARED_MEMORY
     apr_shm_t *cache_shm;
     apr_rmm_t *cache_rmm;
+#if APR_HAS_THREADS
+    apr_thread_mutex_t *lock;
+    apr_anylock_t cache_rmm_anylock;
+#endif
 #endif

     /* cache ald */
diff -Naur httpd-2.4.16\modules\ldap\util_ldap_cache.c
httpd-2.4.16-ea\modules\ldap\util_ldap_cache.c
--- httpd-2.4.16\modules\ldap\util_ldap_cache.c    Mon Aug 19 04:45:19 2013
+++ httpd-2.4.16-ea\modules\ldap\util_ldap_cache.c    Mon Aug 29 10:23:04 2016
@@ -410,6 +410,14 @@
         st->cache_shm = NULL;
         return result;
     }
+
+#if APR_HAS_THREADS
+    apr_thread_mutex_destroy(st->lock);
+    st->lock = NULL;
+    st->cache_rmm_anylock.type = apr_anylock_none;
+    st->cache_rmm_anylock.lock.pm = NULL;
+#endif
+
 #endif
     return APR_SUCCESS;
 }
@@ -436,8 +444,18 @@
         /* Determine the usable size of the shm segment. */
         size = apr_shm_size_get(st->cache_shm);

+#if APR_HAS_THREADS
+        apr_thread_mutex_create(&st->lock, APR_THREAD_MUTEX_DEFAULT,
st->pool);
+        st->cache_rmm_anylock.type = apr_anylock_threadmutex;
+        st->cache_rmm_anylock.lock.tm = st->lock;
+#else
+        st->lock = NULL;
+        st->cache_rmm_anylock.type = apr_anylock_none;
+        st->cache_rmm_anylock.lock.pm = NULL;
+#endif
+
         /* This will create a rmm "handler" to get into the shared memory area
*/
-        result = apr_rmm_init(&st->cache_rmm, NULL,
+        result = apr_rmm_init(&st->cache_rmm, &st->cache_rmm_anylock,
                               apr_shm_baseaddr_get(st->cache_shm), size,
                               st->pool);
         if (result != APR_SUCCESS) {


Thanks!

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to