php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79501 TLS connections freezing on 7.4 (all versions after 7.3.17)
Submitted: 2020-04-20 17:30 UTC Modified: 2020-05-08 11:41 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: imnieves at gmail dot com Assigned:
Status: Re-Opened Package: OpenSSL related
PHP Version: 7.4.5 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please — but make sure to vote on the bug!
Your email address:
MUST BE VALID
Solve the problem:
2 + 22 = ?
Subscribe to this entry?

 
 [2020-04-20 17:30 UTC] imnieves at gmail dot com
Description:
------------
Several users of phpredis (a PHP interface to Redis) have noticed (in php from 7.4.0 and onwards) that TLS connections to Redis "freeze".  This seems to mean that the connection stops or otherwise times out.  When we establish non-TLS connections to Redis (using the same phpredis), we experience no "freeze".  This seems to indicate that something in OpenSSL, or perhaps PHP itself, changed which led to the freezing behavior.

I have personally verified the issue exists on all versions of 7.4 from 7.4.0 to 7.4.5, and that the issue does not exists on version 7.3.17


Some more details and description exists at:
https://github.com/phpredis/phpredis/issues/1726

Test script:
---------------
Some testing setup exists at:
https://github.com/phpredis/phpredis/issues/1726

Expected result:
----------------
The expectation is that TLS connections do not "freeze".


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-04-20 18:47 UTC] stas@php.net
-Status: Open +Status: Suspended -Type: Security +Type: Bug
 [2020-04-20 18:47 UTC] stas@php.net
I don't think "something in OpenSSL, or perhaps PHP itself, changed" is an actionable data that we could do anything with. If you have some specific reproducible issue traceable to PHP core or PHP extension covered by bugs.php.net, please reopen with specific information.
 [2020-04-20 22:28 UTC] imnieves at gmail dot com
I hope the information below is helpful, or at least enough to re-open.

==============================

From the previously mentioned website:

<?php

function l($message)
{
    global $current;
    echo $message . ' (' . (microtime(true) - $current) . ')' . PHP_EOL;
    $current = microtime(true);
}

ini_set('default_socket_timeout', 5);

$start = microtime(true);
$current = microtime(true);

l('start');
$redis = new Redis();
if (!$redis->connect('tls://redis-instance', 25061, 5, null, 5, 5)) {
    throw new RuntimeException($redis->getLastError());
}
l('connected');
$redis->setOption(Redis::OPT_READ_TIMEOUT, 5);
l('option is set');
$redis->auth('some-password');
l('auth complete');
$redis->select(4);
l('db selected');

echo 'Total: ' . (microtime(true) - $start) . PHP_EOL;

=========================

"occasionally this script hangs up for 300 seconds:"

=========================

user:~$ while true; do php redis.php; done
start (5.9604644775391E-6)
connected (0.017167091369629)
option is set (5.0067901611328E-6)
auth complete (0.00058794021606445)
db selected (0.00032281875610352)
Total: 0.018187999725342
start (4.0531158447266E-6)
connected (0.012931108474731)
option is set (7.1525573730469E-6)
auth complete (0.00078892707824707)
db selected (0.00040698051452637)
Total: 0.014256000518799
start (4.0531158447266E-6)
connected (0.01163911819458)
option is set (1.0967254638672E-5)
auth complete (300.07370495796)
db selected (0.00037598609924316)
Total: 300.08729100227

==========================

strace log:

==========================

write(3, "\27\3\3\0006[O\21\240\275|H\243\356\344\16\277\215\243\362h;\350*<N@\24\25\225\254["..., 59) = 59
fcntl(3, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(3, F_SETFL, O_RDWR)               = 0
poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
read(3, "\27\3\3\0\26", 5)              = 5
read(3, "\262\341\277k3\317O\3143X\232\313\310\2742\246\v\203\341\332T\261", 22) = 22
fcntl(3, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(3, F_SETFL, O_RDWR)               = 0
write(1, "2020-03-17 10:49:05 auth complet"..., 522020-03-17 10:49:05 auth complete (300.79558706284)
) = 52
poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
write(3, "\27\3\3\0(\245\360\223\217\252\375p\311\324\246\323\1\303\243\360\343\302\2:\214\5'\"\224\32\2500"..., 45) = 45
fcntl(3, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(3, F_SETFL, O_RDWR)               = 0
poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
read(3, "\27\3\3\0\26", 5)              = 5
read(3, "\327n\353\321\367\354\317[\274&\316)\237C\304\305\275\343\4\266\334\10", 22) = 22
fcntl(3, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(3, F_SETFL, O_RDWR)               = 0
write(1, "2020-03-17 10:49:05 db selected "..., 542020-03-17 10:49:05 db selected (0.00063395500183105)
 [2020-05-04 14:52 UTC] nikic@php.net
-Status: Suspended +Status: Re-Opened
 [2020-05-04 14:52 UTC] nikic@php.net
One relevant difference that comes to mind is that PHP 7.4 will negotiate TLS 1.3 by default. Do you know which TLS version actually gets used?
 [2020-05-06 19:00 UTC] imnieves at gmail dot com
I will investigate
 [2020-05-06 20:51 UTC] imnieves at gmail dot com
I have verified that TLS 1.2 connections work consistently, while TLS 1.3 connections freeze (fail to establish) on PHP 7.4.5-fpm.

On the other side of the testing, both TLS 1.2 and TLS 1.3 connections work consistently on PHP 7.3.17-fpm.

To perform this test I put nginx in front of my Redis, disabled TLS on Redis entirely, and enabled TLS on nginx. I varied the TLS settings on nginx as follows: TLS 1.2 only, then TLS 1.3 only, then both TLS 1.2 and TLS 1.3.

Interesting to note, when nginx has:

only TLS 1.2, the connections always work
only TLS 1.3, the connections always freeze
both TLS 1.2 and TLS 1.3, the connections work for the first 5 attempts, and then one freezes. If I attempt another connection then the next 4 or 5 connections succeed and then another one freezes. And this cycle repeats.
 [2020-05-06 20:54 UTC] imnieves at gmail dot com
In a separate method of testing, I constrained TLS versions of phpredis (instead of constraining TLS versions of nginx)

In this way I have verified on php 7.4.5-fpm that TLS 1.2 results in consistent working connections. TLS 1.3 results in some connections that work and most other connections that fail.

I can also say the cipher suite being used in all my TLS 1.3 connections (consistent and freezing): TLS_AES_256_GCM_SHA384
 [2020-05-08 11:41 UTC] cmb@php.net
-Package: *Encryption and hash functions +Package: OpenSSL related
 [2020-05-08 11:41 UTC] cmb@php.net
According to a comment on the PhpRedis issue[1] this might be an
issue with our tlsv1.3 stream wrapper implementation:

| […] because right now it looks like something may be wrong in
| PhpRedis even if it just wraps php streams.

[1] <https://github.com/phpredis/phpredis/issues/1726#issuecomment-625319182>
 [2020-08-08 17:58 UTC] imnieves at gmail dot com
According to comment from a maintainer of PhpRedis[1], they feel that the issue is not coming from PhpRedis itself:

| I'm going to close this issue because it is actually not a bug in phpredis.

[1] https://github.com/phpredis/phpredis/issues/1726#issuecomment-652563196
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sat Dec 05 22:01:23 2020 UTC