php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71507 Overflow in php_tvtoto
Submitted: 2016-02-03 11:58 UTC Modified: 2016-10-17 16:36 UTC
From: martijn at hexon dot cx Assigned:
Status: Open Package: Network related
PHP Version: 5.6.17 OS:
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:
10 + 13 = ?
Subscribe to this entry?

 
 [2016-02-03 11:58 UTC] martijn at hexon dot cx
Description:
------------
php_tvtoto() in main/php_network.h converts a struct timeval to a timeout in seconds.

In some cases php_tvtoto() is called with a large value for tv_sec, causing the resulting integer to overflow.

For example with mysqlnd, where the default value for mysqlnd.net_read_timeout is 31536000 (one year, in seconds)

poll([{fd=13, events=POLLIN|POLLERR|POLLHUP}], 1, 1471228928) = 1 ([{fd=13, revents=POLLIN}])

#0  0x00007f47000bbe88 in poll () from /lib64/libc.so.6
#1  0x0000000000801399 in php_pollfd_for (stream=<value optimized out>, buf=<value optimized out>, count=<value optimized out>) at /usr/src/php-5.6.17/main/php_network.h:165
#2  php_sockop_write (stream=<value optimized out>, buf=<value optimized out>, count=<value optimized out>) at /usr/src/php-5.6.17/main/streams/xp_socket.c:82
#3  0x000000000047fee0 in php_openssl_sockop_io (read=0, stream=<value optimized out>, buf=<value optimized out>, count=18446744073709551615) at /usr/src/php-5.6.17/ext/openssl/xp_ssl.c:1971
#4  0x00000000007f4457 in _php_stream_write_buffer (stream=0xeadb090, buf=0x148d0780 "e-querylarge-querylarge-querylarge-querylarge-"..., count=25467)
    at /usr/src/php-5.6.17/main/streams/streams.c:1133
#5  0x00000000007c9eec in php_mysqlnd_net_send_ex_pub (net=0x105bb7e0, buffer=0x148cb2a8 "O\270", count=<value optimized out>, conn_stats=<value optimized out>, error_info=<value optimized out>) at /usr/src/php-5.6.17/ext/mysqlnd/mysqlnd_net.c:447
...

31536000 * 1000 mod 2^32 = 1471228928

So poll times out after ~17 days instead of 365 days.

Test script:
---------------
test.php:
<?php
  $db = new mysqli(...);

  // Prepare large query to fill the output buffer causing mysqlnd
  // to call php_pollfd_for()
  $largeSQL = 'SELECT "'. str_repeat('large-query', 1000000) .'"';
  $db->query($largeSQL);
?>

strace test.php

Expected result:
----------------
poll([{fd=4, events=POLLOUT}], 1, 4294967296) = 1 ([{fd=4, revents=POLLOUT}])

(or maybe a timeout of -1 is better)

Actual result:
--------------
poll([{fd=4, events=POLLOUT}], 1, 1471228928) = 1 ([{fd=4, revents=POLLOUT}])


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-07-02 14:43 UTC] cmb@php.net
Presuming that int is at least 32bit on all supported platforms,
this issue appears to be academic, as timeouts up to 596 hours
(i.e. more than 24 days) would be supported.

Shouldn't we just adjust mysqlnd.net_read_timeout to default to a
smaller value? 1 day appears to be more than sufficient.
 [2016-10-17 16:36 UTC] andrey@php.net
This got fixed in mysqlnd, as of today, and the timeour is now just 24 hours == no overflow.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Mon Dec 09 16:01:24 2019 UTC