Bug #73929 [Com]: SSL client socket errors under load with SSL_CTX_new:null ssl method passed in
| From: | henryg at valvesoftware dot com | Date: | Fri, 27 Jan 2017 23:30:00 +0000 |
| Subject: | Bug #73929 [Com]: SSL client socket errors under load with SSL_CTX_new:null ssl method passed in | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-206986@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=73929&edit=1
ID: 73929
Comment by: henryg at valvesoftware dot com
Reported by: tonyp at valvesoftware dot com
Summary: SSL client socket errors under load with
SSL_CTX_new:null ssl method passed in
Status: Open
Type: Bug
Package: Sockets related
Operating System: Ubuntu 16.04
PHP Version: 7.0.14
Block user comment: N
Private report: N
New Comment:
The bug is actually that the CURL extension doesn't always clear the OpenSSL error stack upon
encountering an error, and then later the PHP socket implementation unconditionally checks
SSL_get_error even when the return value from SSL_read or SSL_write is positive (which should
indicate no error). PHP then believes that the error was related to the socket operation and aborts
the operation, when really the error was unrelated and just happened to be sitting on the OpenSSL
error stack.
Previous Comments:
------------------------------------------------------------------------
[2017-01-14 00:19:51] tonyp at valvesoftware dot com
Description:
------------
Almost every hit to our web server makes a socket request to another server. Under load, when using
PHP 7, we get errors like the following:
[Fri Jan 13 15:27:28.692030 2017] [proxy_fcgi:error] [pid 2362] [client <redacted>:60929]
AH01071: Got error 'PHP message: PHP Warning: fread(): SSL operation failed with code 1.
OpenSSL Error messages:\nerror:140A90C4:SSL routines:SSL_CTX_new:null ssl method passed in
<redacted>
[Fri Jan 13 15:27:28.751464 2017] [proxy_fcgi:error] [pid 1960] [client <redacted>:61262]
AH01071: Got error 'PHP message: PHP Warning: fread(): SSL operation failed with code 1.
OpenSSL Error messages:\nerror:140A90C4:SSL routines:SSL_CTX_new:null ssl method passed in
<redacted>
[Fri Jan 13 15:27:29.404802 2017] [proxy_fcgi:error] [pid 2362] [client <redacted>:60929]
AH01071: Got error 'PHP message: PHP Warning: fread(): SSL operation failed with code 1.
OpenSSL Error messages:\nerror:140A90C4:SSL routines:SSL_CTX_new:null ssl method passed in
<redacted>
[Fri Jan 13 15:27:29.487308 2017] [proxy_fcgi:error] [pid 2346] [client <redacted>:63548]
AH01071: Got error 'PHP message: PHP Warning: fread(): SSL operation failed with code 1.
OpenSSL Error messages:\nerror:140A90C4:SSL routines:SSL_CTX_new:null ssl method passed in
<redacted>
[Fri Jan 13 15:27:29.668853 2017] [proxy_fcgi:error] [pid 2420] [client <redacted>:42796]
AH01071: Got error 'PHP message: PHP Warning: fread(): SSL operation failed with code 1.
OpenSSL Error messages:\nerror:140A90C4:SSL routines:SSL_CTX_new:null ssl method passed in
<redacted>
I have verified that it's actually a socket resource being passed into fread.
We do not get these errors in PHP 5. We do not get errors when using non-SSL sockets. Using
persistent sockets seems to make the errors occur more frequently, but the problem still occurs when
not using persistent sockets. We do use non-SSL persistent sockets elsewhere for things like
connections to memcache (Memcache::pconnect).
I have tried PHP as an Apache module, and I have tried PHP-FPM. The problem occurs in both.
Unfortunately, I have not been able to come up with a reliable repro test script. I have got the
error to occur in a script that spins up 1,000 forks and has each fork connect and send data back
and forth using SSL sockets, but it's very unreliable. I'm not sure what's happening
in production to make the error happen more frequently.
The sockets are created using stream_socket_client with the STREAM_CLIENT_CONNECT flag. We create a
context using stream_context_create and set allow_self_signed to true. verify_peer and
verify_peer_name are set to false. I have not been able to verify whether or not the errors occur
without passing or context, or whether or not they occur using fsockopen. The errors occur if even
if a specific cipher is specified, or at least occur with the ciphers I've tried
(ECDHE-RSA-AES256-GCM-SHA384 for example).
The errors occur using ssl://, tls://, and tlsv1.2:// transports. The errors still occur when adding
a random identifier after the ip:port combo, for example: 'tls://10.1.2.3:1234/' .
rand(0,999999).
The code that's failing is an fread call immediately after an fwrite. The fwrite call returns a
positive value as it should, and the fread call fails immediately. I have not verified whether or
not the data sent by the fwrite call preceding the failing fread call is actually received by the
server.
Let me know if there's something I can try that will give you more information about the nature
of the problem.
Test script:
---------------
$context = stream_context_create();
stream_context_set_option( $context, 'ssl', 'allow_self_signed', true );
stream_context_set_option( $context, 'ssl', 'verify_peer', false );
stream_context_set_option( $context, 'ssl', 'verify_peer_name', false );
$this->m_pfSocket = stream_socket_client( 'tlsv1.2://' . $ip . ':' . $port,
$errno, $errstr, 1.0, STREAM_CLIENT_CONNECT, $context );
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=73929&edit=1