You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by jc...@apache.org on 2017/04/19 02:42:43 UTC

svn commit: r1791849 - in /httpd/httpd/trunk: ./ acinclude.m4 docs/ docs/log-message-tags/next-number modules/ssl/ssl_util.c

Author: jchampion
Date: Wed Apr 19 02:42:43 2017
New Revision: 1791849

URL: http://svn.apache.org/viewvc?rev=1791849&view=rev
Log:
Merge fix branch for PR60947.

Modified:
    httpd/httpd/trunk/   (props changed)
    httpd/httpd/trunk/acinclude.m4
    httpd/httpd/trunk/docs/   (props changed)
    httpd/httpd/trunk/docs/log-message-tags/next-number
    httpd/httpd/trunk/modules/ssl/ssl_util.c

Propchange: httpd/httpd/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Apr 19 02:42:43 2017
@@ -1,5 +1,5 @@
 /httpd/httpd/branches/revert-ap-ldap:1150158-1150173
 /httpd/httpd/branches/trunk-buildconf-noapr:1780253-1780970
-/httpd/httpd/branches/trunk-openssl-threadid:1791053-1791054
+/httpd/httpd/branches/trunk-openssl-threadid:1791053-1791848
 /httpd/httpd/branches/trunk-test-integration:1777251-1782067
 /httpd/httpd/branches/wombat-integration:723609-723841

Modified: httpd/httpd/trunk/acinclude.m4
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/acinclude.m4?rev=1791849&r1=1791848&r2=1791849&view=diff
==============================================================================
--- httpd/httpd/trunk/acinclude.m4 (original)
+++ httpd/httpd/trunk/acinclude.m4 Wed Apr 19 02:42:43 2017
@@ -608,7 +608,8 @@ AC_DEFUN([APACHE_CHECK_OPENSSL],[
       liberrors=""
       AC_CHECK_HEADERS([openssl/engine.h])
       AC_CHECK_FUNCS([SSL_CTX_new], [], [liberrors="yes"])
-      AC_CHECK_FUNCS([ENGINE_init ENGINE_load_builtin_engines RAND_egd])
+      AC_CHECK_FUNCS([ENGINE_init ENGINE_load_builtin_engines RAND_egd \
+                      CRYPTO_set_id_callback])
       if test "x$liberrors" != "x"; then
         AC_MSG_WARN([OpenSSL libraries are unusable])
       fi
@@ -653,7 +654,7 @@ AC_DEFUN([APACHE_CHECK_OPENSSL],[
           #include "apr_thread_cond.h"
           #include "apr_thread_proc.h"
 
-          #define NUM_THREADS 3
+          #define NUM_THREADS 10
 
           struct thread_data {
               apr_thread_mutex_t *mutex;
@@ -692,6 +693,7 @@ AC_DEFUN([APACHE_CHECK_OPENSSL],[
           int ret = 0;
           apr_status_t status;
           int i;
+          int j;
 
           apr_pool_t         *pool;
           apr_thread_mutex_t *mutex;
@@ -738,10 +740,13 @@ AC_DEFUN([APACHE_CHECK_OPENSSL],[
           }
 
           /* Check that no addresses were duplicated. */
-          if ((tdata[0].errno_addr == tdata[1].errno_addr)
-              || (tdata[1].errno_addr == tdata[2].errno_addr)
-              || (tdata[0].errno_addr == tdata[2].errno_addr)) {
-              ret = 5;
+          for (i = 0; i < NUM_THREADS - 1; ++i) {
+              for (j = i + 1; j < NUM_THREADS; ++j) {
+                  if (tdata[i].errno_addr == tdata[j].errno_addr) {
+                      ret = 5;
+                      goto out;
+                  }
+              }
           }
 
       out:

Propchange: httpd/httpd/trunk/docs/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Apr 19 02:42:43 2017
@@ -1,4 +1,5 @@
 /httpd/httpd/branches/2.4.x/docs:1537109
 /httpd/httpd/branches/revert-ap-ldap/docs:1150158-1150173
+/httpd/httpd/branches/trunk-openssl-threadid/docs:1791053-1791848
 /httpd/httpd/branches/trunk-test-integration/docs:1777251-1782067
 /httpd/httpd/branches/wombat-integration/docs:723609-723841

Modified: httpd/httpd/trunk/docs/log-message-tags/next-number
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/log-message-tags/next-number?rev=1791849&r1=1791848&r2=1791849&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/log-message-tags/next-number (original)
+++ httpd/httpd/trunk/docs/log-message-tags/next-number Wed Apr 19 02:42:43 2017
@@ -1 +1 @@
-10027
+10031

Modified: httpd/httpd/trunk/modules/ssl/ssl_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_util.c?rev=1791849&r1=1791848&r2=1791849&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_util.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_util.c Wed Apr 19 02:42:43 2017
@@ -252,6 +252,13 @@ void ssl_asn1_table_unset(apr_hash_t *ta
  * To ensure thread-safetyness in OpenSSL - work in progress
  */
 
+#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && \
+        (_WIN32 || __BEOS__ || AP_OPENSSL_USE_ERRNO_THREADID)
+/* Windows and BeOS can use the default THREADID callback shipped with OpenSSL
+ * 1.0.x, as can any platform with a thread-safe errno. */
+# define DEFAULT_THREADID_IS_SAFE 1
+#endif
+
 static apr_thread_mutex_t **lock_cs;
 static int                  lock_num_locks;
 
@@ -363,9 +370,22 @@ static void ssl_dyn_destroy_function(str
     apr_pool_destroy(l->pool);
 }
 
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+#if DEFAULT_THREADID_IS_SAFE
 
-static void ssl_util_thr_id(CRYPTO_THREADID *id)
+/* We don't need to set up a threadid callback on this platform. */
+void ssl_util_thread_id_setup(apr_pool_t *p)
+{
+    ap_log_perror(APLOG_MARK, APLOG_NOTICE, 0, p, APLOGNO(10027)
+                  "using builtin threadid callback for OpenSSL");
+}
+
+#else
+
+/**
+ * Used by both versions of ssl_util_thr_id(). Returns an unsigned long that
+ * should be unique to the currently executing thread.
+ */
+static unsigned long ssl_util_thr_id_internal(void)
 {
     /* OpenSSL needs this to return an unsigned long.  On OS/390, the pthread
      * id is a structure twice that big.  Use the TCB pointer instead as a
@@ -377,46 +397,79 @@ static void ssl_util_thr_id(CRYPTO_THREA
         unsigned long PSATOLD;
     } *psaptr = 0; /* PSA is at address 0 */
 
-    CRYPTO_THREADID_set_numeric(id, psaptr->PSATOLD);
+    return psaptr->PSATOLD;
 #else
-    CRYPTO_THREADID_set_numeric(id, (unsigned long) apr_os_thread_current());
+    return (unsigned long) apr_os_thread_current();
 #endif
 }
 
-static apr_status_t ssl_util_thr_id_cleanup(void *old)
+#if HAVE_CRYPTO_SET_ID_CALLBACK
+
+static unsigned long ssl_util_thr_id(void)
 {
-    CRYPTO_THREADID_set_callback(old);
-    return APR_SUCCESS;
+    return ssl_util_thr_id_internal();
 }
 
 #else
 
-static unsigned long ssl_util_thr_id(void)
+static void ssl_util_thr_id(CRYPTO_THREADID *id)
 {
-    /* OpenSSL needs this to return an unsigned long.  On OS/390, the pthread
-     * id is a structure twice that big.  Use the TCB pointer instead as a
-     * unique unsigned long.
-     */
-#ifdef __MVS__
-    struct PSA {
-        char unmapped[540];
-        unsigned long PSATOLD;
-    } *psaptr = 0;
-
-    return psaptr->PSATOLD;
-#else
-    return (unsigned long) apr_os_thread_current();
-#endif
+    /* XXX Ideally we would be using the _set_pointer() callback on platforms
+     * that have a pointer-based thread "identity". But this entire API is
+     * fraught with problems (see PR60947) and has been removed completely in
+     * OpenSSL 1.1.0, so I'm not too invested in fixing it right now. */
+    CRYPTO_THREADID_set_numeric(id, ssl_util_thr_id_internal());
 }
 
+#endif /* HAVE_CRYPTO_SET_ID_CALLBACK */
+
 static apr_status_t ssl_util_thr_id_cleanup(void *old)
 {
+#if HAVE_CRYPTO_SET_ID_CALLBACK
     CRYPTO_set_id_callback(old);
+#else
+    /* XXX This does nothing. The new-style THREADID callback is write-once. */
+    CRYPTO_THREADID_set_callback(old);
+#endif
+
     return APR_SUCCESS;
 }
 
+void ssl_util_thread_id_setup(apr_pool_t *p)
+{
+#if HAVE_CRYPTO_SET_ID_CALLBACK
+    ap_log_perror(APLOG_MARK, APLOG_NOTICE, 0, p, APLOGNO(10028)
+                  "using deprecated CRYPTO_set_id_callback for OpenSSL");
+
+    /* This API is deprecated, but we prefer it to its replacement since it
+     * allows us to unset the callback when this module is being unloaded. */
+    CRYPTO_set_id_callback(ssl_util_thr_id);
+#else
+    ap_log_perror(APLOG_MARK, APLOG_NOTICE, 0, p, APLOGNO(10029)
+                  "using dangerous CRYPTO_THREADID_set_callback for OpenSSL");
+
+    /* This is a last resort. We can only set this once, which means that we'd
+     * better not get loaded into a different address during a restart. See
+     * PR60947. */
+    CRYPTO_THREADID_set_callback(ssl_util_thr_id);
+
+    if (CRYPTO_THREADID_get_callback() != ssl_util_thr_id) {
+        /* XXX Unfortunately this doesn't seem to get logged unless you're
+         * running in one-process mode, due to PR60999. */
+        ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, p, APLOGNO(10030)
+            "OpenSSL's THREADID callback was already set to another address, "
+            "and the server is probably going to crash. See bug #60947 for "
+            "more details. You may need to recompile or upgrade either OpenSSL "
+            "or httpd.");
+    }
 #endif
 
+    apr_pool_cleanup_register(p, NULL, ssl_util_thr_id_cleanup,
+                                       apr_pool_cleanup_null);
+}
+
+#endif /* DEFAULT_THREADID_IS_SAFE */
+
 static apr_status_t ssl_util_thread_cleanup(void *data)
 {
     CRYPTO_set_locking_callback(NULL);
@@ -457,15 +510,5 @@ void ssl_util_thread_setup(apr_pool_t *p
                                        apr_pool_cleanup_null);
 }
 
-void ssl_util_thread_id_setup(apr_pool_t *p)
-{
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-    CRYPTO_THREADID_set_callback(ssl_util_thr_id);
-#else
-    CRYPTO_set_id_callback(ssl_util_thr_id);
-#endif
-    apr_pool_cleanup_register(p, NULL, ssl_util_thr_id_cleanup,
-                                       apr_pool_cleanup_null);
-}
 #endif /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
 #endif /* #if APR_HAS_THREADS */