mirror of
https://github.com/php/php-src.git
synced 2026-03-26 09:12:14 +01:00
- MFH: thread safe SSL crypto locks, fixes bug #33760
This commit is contained in:
2
NEWS
2
NEWS
@@ -17,6 +17,8 @@ PHP NEWS
|
||||
- Fixed bug #34712 (zend.ze1_compatibility_mode = on segfault). (Dmitry)
|
||||
- Fixed bug #33829 (mime_content_type() returns text/plain for gzip and bzip
|
||||
files). (Derick)
|
||||
- Fixed bug #33760 (cURL needs to implement CRYPTO_callback functions to prevent
|
||||
locking). (Mike, Ilia)
|
||||
- Fixed bug #34623 (Crash in pdo_mysql on longtext fields). (Ilia)
|
||||
- Fixed bug #31341 (escape on curly inconsistent). (Dmitry)
|
||||
- Fixed bug #31177 (menory leaks and corruption because of incorrect
|
||||
|
||||
@@ -48,6 +48,38 @@ if test "$PHP_CURL" != "no"; then
|
||||
else
|
||||
AC_MSG_ERROR(cURL version 7.10.5 or later is required to compile php with cURL support)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for SSL support in libcurl])
|
||||
CURL_SSL=`$CURL_CONFIG --features | $EGREP SSL`
|
||||
if test "$CURL_SSL" == "SSL"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_CURL_SSL], [1], [Have cURL with SSL support])
|
||||
|
||||
AC_MSG_CHECKING([for SSL library used])
|
||||
CURL_SSL_FLAVOUR=
|
||||
for i in $CURL_LIBS; do
|
||||
if test "$i" == "-lssl"; then
|
||||
CURL_SSL_FLAVOUR="openssl"
|
||||
AC_MSG_RESULT([openssl])
|
||||
AC_DEFINE([HAVE_CURL_OPENSSL], [1], [Have cURL with OpenSSL support])
|
||||
AC_CHECK_HEADERS([openssl/crypto.h])
|
||||
break
|
||||
elif test "$i" == "-lgnutls"; then
|
||||
CURL_SSL_FLAVOUR="gnutls"
|
||||
AC_MSG_RESULT([gnutls])
|
||||
AC_DEFINE([HAVE_CURL_GNUTLS], [1], [Have cURL with GnuTLS support])
|
||||
AC_CHECK_HEADERS([gcrypt.h])
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$CURL_SSL_FLAVOUR"; then
|
||||
AC_MSG_RESULT([unknown!])
|
||||
AC_MSG_WARN([Could not determine the type of SSL library used!])
|
||||
AC_MSG_WARN([Building will fail in ZTS mode!])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
PHP_ADD_INCLUDE($CURL_DIR/include)
|
||||
PHP_EVAL_LIBLINE($CURL_LIBS, CURL_SHARED_LIBADD)
|
||||
|
||||
@@ -12,6 +12,7 @@ if (PHP_CURL != "no") {
|
||||
CHECK_LIB("winmm.lib", "curl", PHP_CURL)) {
|
||||
EXTENSION("curl", "interface.c multi.c streams.c");
|
||||
AC_DEFINE('HAVE_CURL', 1, 'Have CURL library');
|
||||
AC_DEFINE('HAVE_CURL_SSL', 1, 'Have SSL suppurt in CURL');
|
||||
// TODO: check for curl_version_info
|
||||
// AC_DEFINE('PHP_CURL_URL_WRAPPERS', 0, 'Use curl for URL wrappers [experimental]');
|
||||
} else {
|
||||
|
||||
@@ -44,6 +44,45 @@
|
||||
#define HttpPost curl_httppost
|
||||
#endif
|
||||
|
||||
/* {{{ cruft for thread safe SSL crypto locks */
|
||||
#if defined(ZTS) && defined(HAVE_CURL_SSL)
|
||||
# ifdef PHP_WIN32
|
||||
# define PHP_CURL_NEED_SSL_TSL
|
||||
# define PHP_CURL_NEED_OPENSSL_TSL
|
||||
# include <openssl/crypto.h>
|
||||
# else /* !PHP_WIN32 */
|
||||
# if defined(HAVE_CURL_OPENSSL)
|
||||
# if defined(HAVE_OPENSSL_CRYPTO_H)
|
||||
# define PHP_CURL_NEED_SSL_TSL
|
||||
# define PHP_CURL_NEED_OPENSSL_TSL
|
||||
# include <openssl/crypto.h>
|
||||
# else
|
||||
# warning \
|
||||
"libcurl was compiled with OpenSSL support, but configure could not find " \
|
||||
"openssl/crypto.h; thus no SSL crypto locking callbacks will be set, which may " \
|
||||
"cause random crashes on SSL requests"
|
||||
# endif
|
||||
# elif defined(HAVE_CURL_GNUTLS)
|
||||
# if defined(HAVE_GCRYPT_H)
|
||||
# define PHP_CURL_NEED_SSL_TSL
|
||||
# define PHP_CURL_NEED_GNUTLS_TSL
|
||||
# include <gcrypt.h>
|
||||
# else
|
||||
# warning \
|
||||
"libcurl was compiled with GnuTLS support, but configure could not find " \
|
||||
"gcrypt.h; thus no SSL crypto locking callbacks will be set, which may " \
|
||||
"cause random crashes on SSL requests"
|
||||
# endif
|
||||
# else
|
||||
# warning \
|
||||
"libcurl was compiled with SSL support, but configure could not determine which" \
|
||||
"library was used; thus no SSL crypto locking callbacks will be set, which may " \
|
||||
"cause random crashes on SSL requests"
|
||||
# endif /* HAVE_CURL_OPENSSL || HAVE_CURL_GNUTLS */
|
||||
# endif /* PHP_WIN32 */
|
||||
#endif /* ZTS && HAVE_CURL_SSL */
|
||||
/* }}} */
|
||||
|
||||
#define SMART_STR_PREALLOC 4096
|
||||
|
||||
#include "ext/standard/php_smart_str.h"
|
||||
@@ -55,6 +94,11 @@
|
||||
int le_curl;
|
||||
int le_curl_multi_handle;
|
||||
|
||||
#ifdef PHP_CURL_NEED_SSL_TSL
|
||||
static inline void php_curl_ssl_init(void);
|
||||
static inline void php_curl_ssl_cleanup(void);
|
||||
#endif
|
||||
|
||||
static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC);
|
||||
|
||||
#define SAVE_CURL_ERROR(__handle, __err) (__handle)->err.no = (int) __err;
|
||||
@@ -403,6 +447,9 @@ PHP_MINIT_FUNCTION(curl)
|
||||
REGISTER_CURL_CONSTANT(CURLFTPAUTH_TLS);
|
||||
#endif
|
||||
|
||||
#ifdef PHP_CURL_NEED_SSL_TSL
|
||||
php_curl_ssl_init();
|
||||
#endif
|
||||
if (curl_global_init(CURL_GLOBAL_SSL) != CURLE_OK) {
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -440,7 +487,9 @@ PHP_MSHUTDOWN_FUNCTION(curl)
|
||||
php_unregister_url_stream_wrapper("ldap" TSRMLS_CC);
|
||||
#endif
|
||||
curl_global_cleanup();
|
||||
|
||||
#ifdef PHP_CURL_NEED_SSL_TSL
|
||||
php_curl_ssl_cleanup();
|
||||
#endif
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -1545,7 +1594,106 @@ static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#endif
|
||||
#ifdef PHP_CURL_NEED_OPENSSL_TSL
|
||||
/* {{{ */
|
||||
static MUTEX_T *php_curl_openssl_tsl = NULL;
|
||||
|
||||
static void php_curl_ssl_lock(int mode, int n, const char * file, int line)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK) {
|
||||
tsrm_mutex_lock(php_curl_openssl_tsl[n]);
|
||||
} else {
|
||||
tsrm_mutex_unlock(php_curl_openssl_tsl[n]);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long php_curl_ssl_id(void)
|
||||
{
|
||||
return (unsigned long) tsrm_thread_id();
|
||||
}
|
||||
|
||||
static inline void php_curl_ssl_init(void)
|
||||
{
|
||||
int i, c = CRYPTO_num_locks();
|
||||
|
||||
php_curl_openssl_tsl = malloc(c * sizeof(MUTEX_T));
|
||||
|
||||
for (i = 0; i < c; ++i) {
|
||||
php_curl_openssl_tsl[i] = tsrm_mutex_alloc();
|
||||
}
|
||||
|
||||
CRYPTO_set_id_callback(php_curl_ssl_id);
|
||||
CRYPTO_set_locking_callback(php_curl_ssl_lock);
|
||||
}
|
||||
|
||||
static inline void php_curl_ssl_cleanup(void)
|
||||
{
|
||||
if (php_curl_openssl_tsl) {
|
||||
int i, c = CRYPTO_num_locks();
|
||||
|
||||
CRYPTO_set_id_callback(NULL);
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
|
||||
for (i = 0; i < c; ++i) {
|
||||
tsrm_mutex_free(php_curl_openssl_tsl[i]);
|
||||
}
|
||||
|
||||
free(php_curl_openssl_tsl);
|
||||
php_curl_openssl_tsl = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* PHP_CURL_NEED_OPENSSL_TSL */
|
||||
/* }}} */
|
||||
|
||||
#ifdef PHP_CURL_NEED_GNUTLS_TSL
|
||||
/* {{{ */
|
||||
static int php_curl_ssl_mutex_create(void **m)
|
||||
{
|
||||
if (*((MUTEX_T *) m) = tsrm_mutex_alloc()) {
|
||||
return SUCCESS;
|
||||
} else {
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
static int php_curl_ssl_mutex_destroy(void **m)
|
||||
{
|
||||
tsrm_mutex_free(*((MUTEX_T *) m));
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int php_curl_ssl_mutex_lock(void **m)
|
||||
{
|
||||
return tsrm_mutex_lock(*((MUTEX_T *) m));
|
||||
}
|
||||
|
||||
static int php_curl_ssl_mutex_unlock(void **m)
|
||||
{
|
||||
return tsrm_mutex_unlock(*((MUTEX_T *) m));
|
||||
}
|
||||
|
||||
static struct gcry_thread_cbs php_curl_gnutls_tsl = {
|
||||
GCRY_THREAD_OPTIONS_USER,
|
||||
NULL,
|
||||
php_curl_ssl_mutex_create,
|
||||
php_curl_ssl_mutex_destroy,
|
||||
php_curl_ssl_mutex_lock,
|
||||
php_curl_ssl_mutex_unlock
|
||||
};
|
||||
|
||||
static inline void php_curl_ssl_init(void)
|
||||
{
|
||||
gcry_control(GCRYCTL_SET_THREAD_CBS, &php_curl_gnutls_tsl);
|
||||
}
|
||||
|
||||
static inline void php_curl_ssl_cleanup(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif /* PHP_CURL_NEED_GNUTLS_TSL */
|
||||
/* }}} */
|
||||
|
||||
#endif /* HAVE_CURL */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
||||
Reference in New Issue
Block a user