]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Commit ssl mutex upcall patch
authorSander Temme <sctemme@apache.org>
Thu, 18 Sep 2008 14:34:51 +0000 (14:34 +0000)
committerSander Temme <sctemme@apache.org>
Thu, 18 Sep 2008 14:34:51 +0000 (14:34 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@696662 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
modules/ssl/ssl_engine_init.c
modules/ssl/ssl_util.c

diff --git a/CHANGES b/CHANGES
index e1c6e75dbca81abdb6f7074269515cff87b091b8..d509f77ae3e5c5e42ce35b30f916b54af6a65fc2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.2.10
 
+  *) mod_ssl: implement dynamic mutex callbacks for the benefit of
+     OpenSSL.  [Sander Temme]
+
   *) SECURITY: CVE-2008-2939 (cve.mitre.org)
      mod_proxy_ftp: Prevent XSS attacks when using wildcards in the path of
      the FTP URL. Discovered by Marc Bevand of Rapid7. [Ruediger Pluem]
diff --git a/STATUS b/STATUS
index 73329ece6a50d4f1001b5f0e48f0c834e114933e..31db1cbed1fa22c26b7021d69a28eca5cd872e9d 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -161,18 +161,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK:
    +1: chrisd
    -0: jim (would prefer to see in 2.4, and to push 2.4 out)
 
- * mod_ssl: implement dynamic mutex callbacks for OpenSSL.  This
-   locking infrastructure is currently only used by the chil plugin,
-   and this plugin won't load into OpenSSL 0.9.8 if these upcalls
-   aren't set.  OpenSSL may start using dynamic locks in more places
-   in the future and with this patch, Apache 2.2.x is ready for that.
-   Trunk version of patch: 
-   http://svn.apache.org/viewvc?rev=687550&view=rev
-   http://svn.apache.org/viewvc?rev=687819&view=rev
-   Single patch against branches/2.2.x: 
-   http://people.apache.org/~sctemme/httpd-2.2.x-ssl-upcalls.diff
-   +1: sctemme, rpluem, jerenkrantz
-
  * INSTALL: Provide a breadcrumb as to why you would use --with-included-apr
    Trunk version of patch:
      http://svn.apache.org/viewvc?rev=696006&view=rev
index 268f7f24a136667dad45fff624000c53f9a076ce..8e3cef8f01a68155d85eaed97aef337a796dc14e 100644 (file)
@@ -321,6 +321,9 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p)
             ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
             ssl_die();
         }
+        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, 
+                     "Init: loaded Crypto Device API `%s'", 
+                     mc->szCryptoDevice);
 
         ENGINE_free(e);
     }
index 88410849bb091b78772161407c9fd78366d47cab..e4387e6181f27055d859680eab661c8a1bd54ca5 100644 (file)
@@ -305,6 +305,114 @@ static void ssl_util_thr_lock(int mode, int type,
     }
 }
 
+/* Dynamic lock structure */
+struct CRYPTO_dynlock_value {
+    apr_pool_t *pool;
+    const char* file; 
+    int line;
+    apr_thread_mutex_t *mutex;
+};
+
+/* Global reference to the pool passed into ssl_util_thread_setup() */
+apr_pool_t *dynlockpool = NULL;
+
+/*
+ * Dynamic lock creation callback
+ */
+static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file, 
+                                                     int line)
+{
+    struct CRYPTO_dynlock_value *value;
+    apr_pool_t *p;
+    apr_status_t rv;
+
+    /* 
+     * We need a pool to allocate our mutex.  Since we can't clear
+     * allocated memory from a pool, create a subpool that we can blow
+     * away in the destruction callback. 
+     */
+    rv = apr_pool_create(&p, dynlockpool);
+    if (rv != APR_SUCCESS) {
+        ap_log_perror(file, line, APLOG_ERR, rv, dynlockpool, 
+                       "Failed to create subpool for dynamic lock");
+        return NULL;
+    }
+
+    ap_log_perror(file, line, APLOG_DEBUG, 0, p, 
+                  "Creating dynamic lock");
+    
+    value = (struct CRYPTO_dynlock_value *)apr_palloc(p, 
+                                                      sizeof(struct CRYPTO_dynlock_value));
+    if (!value) {
+        ap_log_perror(file, line, APLOG_ERR, 0, p, 
+                      "Failed to allocate dynamic lock structure");
+        return NULL;
+    }
+    
+    value->pool = p;
+    /* Keep our own copy of the place from which we were created,
+       using our own pool. */
+    value->file = apr_pstrdup(p, file);
+    value->line = line;
+    rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT, 
+                                p);
+    if (rv != APR_SUCCESS) {
+        ap_log_perror(file, line, APLOG_ERR, rv, p, 
+                      "Failed to create thread mutex for dynamic lock");
+        apr_pool_destroy(p);
+        return NULL;
+    }
+    return value;
+}
+
+/*
+ * Dynamic locking and unlocking function
+ */
+
+static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
+                           const char *file, int line)
+{
+    apr_status_t rv;
+
+    if (mode & CRYPTO_LOCK) {
+        ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool, 
+                      "Acquiring mutex %s:%d", l->file, l->line);
+        rv = apr_thread_mutex_lock(l->mutex);
+        ap_log_perror(file, line, APLOG_DEBUG, rv, l->pool, 
+                      "Mutex %s:%d acquired!", l->file, l->line);
+    }
+    else {
+        ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool, 
+                      "Releasing mutex %s:%d", l->file, l->line);
+        rv = apr_thread_mutex_unlock(l->mutex);
+        ap_log_perror(file, line, APLOG_DEBUG, rv, l->pool, 
+                      "Mutex %s:%d released!", l->file, l->line);
+    }
+}
+
+/*
+ * Dynamic lock destruction callback
+ */
+static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l, 
+                          const char *file, int line)
+{
+    apr_status_t rv;
+
+    ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool, 
+                  "Destroying dynamic lock %s:%d", l->file, l->line);
+    rv = apr_thread_mutex_destroy(l->mutex);
+    if (rv != APR_SUCCESS) {
+        ap_log_perror(file, line, APLOG_ERR, rv, l->pool, 
+                      "Failed to destroy mutex for dynamic lock %s:%d", 
+                      l->file, l->line);
+    }
+
+    /* Trust that whomever owned the CRYPTO_dynlock_value we were
+     * passed has no future use for it...
+     */
+    apr_pool_destroy(l->pool);
+}
+
 static unsigned long ssl_util_thr_id(void)
 {
     /* OpenSSL needs this to return an unsigned long.  On OS/390, the pthread
@@ -327,6 +435,12 @@ static apr_status_t ssl_util_thread_cleanup(void *data)
 {
     CRYPTO_set_locking_callback(NULL);
     CRYPTO_set_id_callback(NULL);
+    
+    CRYPTO_set_dynlock_create_callback(NULL);
+    CRYPTO_set_dynlock_lock_callback(NULL);
+    CRYPTO_set_dynlock_destroy_callback(NULL);
+    
+    dynlockpool = NULL;
 
     /* Let the registered mutex cleanups do their own thing
      */
@@ -347,6 +461,14 @@ void ssl_util_thread_setup(apr_pool_t *p)
     CRYPTO_set_id_callback(ssl_util_thr_id);
 
     CRYPTO_set_locking_callback(ssl_util_thr_lock);
+    
+    /* Set up dynamic locking scaffolding for OpenSSL to use at its
+     * convenience. 
+     */
+    dynlockpool = p;
+    CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
+    CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function);
+    CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function);
 
     apr_pool_cleanup_register(p, NULL, ssl_util_thread_cleanup,
                                        apr_pool_cleanup_null);