Skip to content

Commit 98e67ad

Browse files
committed
Merge branch 'PHP-5.5' into PHP-5.6
* PHP-5.5: Bug #41631: Observe socket read timeouts in SSL streams Conflicts: ext/openssl/xp_ssl.c
2 parents 2cdc1a2 + 5ac2e5f commit 98e67ad

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

ext/openssl/xp_ssl.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,13 +1798,59 @@ static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size
17981798
}
17991799
/* }}} */
18001800

1801+
static void php_openssl_stream_wait_for_data(php_netstream_data_t *sock TSRMLS_DC)
1802+
{
1803+
int retval;
1804+
struct timeval *ptimeout;
1805+
1806+
if (sock->socket == -1) {
1807+
return;
1808+
}
1809+
1810+
sock->timeout_event = 0;
1811+
1812+
if (sock->timeout.tv_sec == -1)
1813+
ptimeout = NULL;
1814+
else
1815+
ptimeout = &sock->timeout;
1816+
1817+
while(1) {
1818+
retval = php_pollfd_for(sock->socket, PHP_POLLREADABLE, ptimeout);
1819+
1820+
if (retval == 0)
1821+
sock->timeout_event = 1;
1822+
1823+
if (retval >= 0)
1824+
break;
1825+
1826+
if (php_socket_errno() != EINTR)
1827+
break;
1828+
}
1829+
}
1830+
18011831
static size_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) /* {{{ */
18021832
{
18031833
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
1834+
php_netstream_data_t *sock;
18041835
int nr_bytes = 0;
18051836

18061837
if (sslsock->ssl_active) {
18071838
int retry = 1;
1839+
sock = (php_netstream_data_t*)stream->abstract;
1840+
1841+
/* The SSL_read() function will block indefinitely waiting for data on a blocking
1842+
socket. If we don't poll for readability first this operation has the potential
1843+
to hang forever. To avoid this scenario we poll with a timeout before performing
1844+
the actual read. If it times out we're finished.
1845+
*/
1846+
if (sock->is_blocked) {
1847+
php_openssl_stream_wait_for_data(sock);
1848+
if (sock->timeout_event) {
1849+
stream->eof = 1;
1850+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL read operation timed out");
1851+
return nr_bytes;
1852+
}
1853+
}
18081854

18091855
do {
18101856
nr_bytes = SSL_read(sslsock->ssl_handle, buf, count);

0 commit comments

Comments
 (0)