From: Daniel Lowrey Date: Mon, 9 Mar 2015 22:02:04 +0000 (-0600) Subject: Merge branch 'PHP-5.6' X-Git-Tag: PRE_PHP7_NSAPI_REMOVAL~730 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=748433e7bcedba58fa7057a048b8b257279a2569;p=php Merge branch 'PHP-5.6' * PHP-5.6: Fix crypto stream timeout regressions Conflicts: ext/openssl/xp_ssl.c --- 748433e7bcedba58fa7057a048b8b257279a2569 diff --cc ext/openssl/xp_ssl.c index a7902cd71c,19a9b17abd..1b5bba73e0 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@@ -2031,27 -1824,22 +2031,28 @@@ static size_t php_openssl_sockop_io(in if (sslsock->ssl_active) { int retry = 1; struct timeval start_time; - struct timeval *timeout; - int blocked = sslsock->s.is_blocked; + struct timeval *timeout = NULL; + int began_blocked = sslsock->s.is_blocked; int has_timeout = 0; + int nr_bytes = 0; + + /* prevent overflow in openssl */ + if (count > INT_MAX) { + count = INT_MAX; + } - /* Begin by making the socket non-blocking. This allows us to check the timeout. */ - if (SUCCESS == php_set_sock_blocking(sslsock->s.socket, 0)) { - sslsock->s.is_blocked = 0; + /* never use a timeout with non-blocking sockets */ + if (began_blocked && &sslsock->s.timeout) { + timeout = &sslsock->s.timeout; } - /* Get the timeout value (and make sure we are to check it. */ - timeout = sslsock->is_client ? &sslsock->connect_timeout : &sslsock->s.timeout; - has_timeout = !sslsock->s.is_blocked && (timeout->tv_sec || timeout->tv_usec); + if (timeout && php_set_sock_blocking(sslsock->s.socket, 0 TSRMLS_CC) == SUCCESS) { + sslsock->s.is_blocked = 0; + } - /* gettimeofday is not monotonic; using it here is not strictly correct */ - if (has_timeout) { + if (!sslsock->s.is_blocked && timeout && (timeout->tv_sec || timeout->tv_usec)) { + has_timeout = 1; + /* gettimeofday is not monotonic; using it here is not strictly correct */ gettimeofday(&start_time, NULL); } @@@ -2064,15 -1852,16 +2065,16 @@@ gettimeofday(&cur_time, NULL); /* Determine how much time we've taken so far. */ - elapsed_time = subtract_timeval( cur_time, start_time ); + elapsed_time = subtract_timeval(cur_time, start_time); /* and return an error if we've taken too long. */ - if (compare_timeval( elapsed_time, *timeout) > 0 ) { + if (compare_timeval(elapsed_time, *timeout) > 0 ) { /* If the socket was originally blocking, set it back. */ - if (blocked) { + if (began_blocked) { - php_set_sock_blocking(sslsock->s.socket, 1 TSRMLS_CC); + php_set_sock_blocking(sslsock->s.socket, 1); sslsock->s.is_blocked = 1; } + sslsock->s.timeout_event = 1; return -1; } } @@@ -2134,12 -1923,11 +2136,12 @@@ int err = SSL_get_error(sslsock->ssl_handle, nr_bytes); /* If we didn't get any error, then let's return it to PHP. */ - if (err == SSL_ERROR_NONE) - break; + if (err == SSL_ERROR_NONE) { + break; + } /* Otherwise, we need to wait again (up to time_left or we get an error) */ - if (blocked) { + if (began_blocked) { if (read) { php_pollfd_for(sslsock->s.socket, (err == SSL_ERROR_WANT_WRITE) ? (POLLOUT|POLLPRI) : (POLLIN|POLLPRI), has_timeout ? &left_time : NULL); @@@ -2159,26 -1946,26 +2161,25 @@@ } /* And if we were originally supposed to be blocking, let's reset the socket to that. */ - if (blocked) { - php_set_sock_blocking(sslsock->s.socket, 1); - if (began_blocked && php_set_sock_blocking(sslsock->s.socket, 1 TSRMLS_CC) == SUCCESS) { ++ if (began_blocked && php_set_sock_blocking(sslsock->s.socket, 1) == SUCCESS) { sslsock->s.is_blocked = 1; } + + return 0 > nr_bytes ? 0 : nr_bytes; } else { + size_t nr_bytes = 0; + /* - * This block is if we had no timeout... We will just sit and wait forever on the IO operation. + * This block is if we had no timeout... We will just sit and wait forever on the IO operation. */ if (read) { - nr_bytes = php_stream_socket_ops.read(stream, buf, count TSRMLS_CC); + nr_bytes = php_stream_socket_ops.read(stream, buf, count); } else { - nr_bytes = php_stream_socket_ops.write(stream, buf, count TSRMLS_CC); + nr_bytes = php_stream_socket_ops.write(stream, buf, count); } - } - /* PHP doesn't expect a negative return. */ - if (nr_bytes < 0) { - nr_bytes = 0; + return nr_bytes; } - - return nr_bytes; } /* }}} */