Commit 5103c6c8 authored by Sander Temme's avatar Sander Temme
Browse files

Commit ssl mutex upcall patch

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@696662 13f79535-47bb-0310-9956-ffa450edef68
parent 94824618
Loading
Loading
Loading
Loading
+3 −0
Changes for CHANGES: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
                                                         -*- 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]
+0 −12
Changes for STATUS: 0 added lines, 12 removed lines.
Original line number Diff line number Diff line
@@ -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
+3 −0
Changes for modules/ssl/ssl_engine_init.c: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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);
    }
+122 −0
Changes for modules/ssl/ssl_util.c: 122 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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
@@ -328,6 +436,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
     */
    return APR_SUCCESS;
@@ -348,6 +462,14 @@ void ssl_util_thread_setup(apr_pool_t *p)

    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);
}