Skip to content

Commit 6569db8

Browse files
committed
Bug #41631: Observe socket read timeouts in SSL streams
1 parent 7189039 commit 6569db8

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
@@ -204,13 +204,59 @@ static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size
204204
return didwrite;
205205
}
206206

207+
static void php_openssl_stream_wait_for_data(php_netstream_data_t *sock TSRMLS_DC)
208+
{
209+
int retval;
210+
struct timeval *ptimeout;
211+
212+
if (sock->socket == -1) {
213+
return;
214+
}
215+
216+
sock->timeout_event = 0;
217+
218+
if (sock->timeout.tv_sec == -1)
219+
ptimeout = NULL;
220+
else
221+
ptimeout = &sock->timeout;
222+
223+
while(1) {
224+
retval = php_pollfd_for(sock->socket, PHP_POLLREADABLE, ptimeout);
225+
226+
if (retval == 0)
227+
sock->timeout_event = 1;
228+
229+
if (retval >= 0)
230+
break;
231+
232+
if (php_socket_errno() != EINTR)
233+
break;
234+
}
235+
}
236+
207237
static size_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
208238
{
209239
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
240+
php_netstream_data_t *sock;
210241
int nr_bytes = 0;
211242

212243
if (sslsock->ssl_active) {
213244
int retry = 1;
245+
sock = (php_netstream_data_t*)stream->abstract;
246+
247+
/* The SSL_read() function will block indefinitely waiting for data on a blocking
248+
socket. If we don't poll for readability first this operation has the potential
249+
to hang forever. To avoid this scenario we poll with a timeout before performing
250+
the actual read. If it times out we're finished.
251+
*/
252+
if (sock->is_blocked) {
253+
php_openssl_stream_wait_for_data(sock);
254+
if (sock->timeout_event) {
255+
stream->eof = 1;
256+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL read operation timed out");
257+
return nr_bytes;
258+
}
259+
}
214260

215261
do {
216262
nr_bytes = SSL_read(sslsock->ssl_handle, buf, count);

0 commit comments

Comments
 (0)