php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65486 mysqli_poll() is broken on win x64
Submitted: 2013-08-20 09:01 UTC Modified: 2013-12-13 15:12 UTC
From: ab@php.net Assigned: ab
Status: Closed Package: MySQLi related
PHP Version: 5.5Git-2013-08-20 (Git) OS: Windows 64 Bit
Private report: No CVE-ID:
 [2013-08-20 09:01 UTC] ab@php.net
Description:
------------
mysqli_poll() in user space invokes _mysqlnd_poll(). In that function 
php_select()  
is used for polling. The windows implementation works with int for descriptors, 
however php_socket_t data type is used in mysqli. This has two flaws

- generally on windows, php_socket_t is a typedef from SOCKET and is unsigned, 
that means any usual UNIX socket checks want work, say checking if descriptor is 
negative

- on 64 bit windows this is a breach, because SOCKET there is unsigned 64 bit 
integer while php_select() implementation still uses 32 bit integers. 
php_select()  
internally calls select(), which on windows expects an 32 bit integer as 
descriptor as well.

As result mysqli_poll* function family is broken on 64 bit Windows.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-08-20 09:02 UTC] ab@php.net
-Assigned To: +Assigned To: mysql
 [2013-12-03 14:33 UTC] andrey@php.net
-Status: Assigned +Status: Feedback
 [2013-12-03 14:33 UTC] andrey@php.net
Anatol,
except for the bug that mysqlnd converts internally the int to uint when passing back through an out desc_num parameter of _mysqlnd_poll() everything else is more or less copied from another part of the distribution. The code exists in 2 places : streamfuncs.c and sockets.c (search for "Solaris + BSD"). Is the code in this places also not correct?

Best,
Andrey
 [2013-12-03 19:45 UTC] ab@php.net
-Status: Feedback +Status: Assigned
 [2013-12-03 19:45 UTC] ab@php.net
Hi Andrey,

that's true, i also can see some similar code in the cli server. Regarding windows, especially 64 bit, i'd call it "fail ready". In linux there's no disctinction between file descriptor and socket descriptor, both are some integer and 32 bit on x86 and x64 platform. On windows there's ditinction between SOCKET and file descriptor, whereby SOCKET is unsigned and additionally 64 bit on x64 platform. I can't tell why it works in other cases :) ... just haven't time to debug deep. For instance I can imagine this flow could be breaking the max_fd variable in _mysqlnd_poll()

php5ts_debug.dll!php_sockop_cast(_php_stream * stream, int castas, void * * ret, void * * * tsrm_ls) Line 429	C
php5ts_debug.dll!_php_stream_cast(_php_stream * stream, int castas, void * * ret, int show_err, void * * * tsrm_ls) Line 309	C
php5ts_debug.dll!mysqlnd_stream_array_to_fd_set(st_mysqlnd_connection * * conn_array, fd_set * fds, unsigned __int64 * max_fd, void * * * tsrm_ls) Line 1280	C
php5ts_debug.dll!_mysqlnd_poll(st_mysqlnd_connection * * r_array, st_mysqlnd_connection * * e_array, st_mysqlnd_connection * * * dont_poll, long sec, long usec, unsigned int * desc_num, void * * * tsrm_ls) Line 1361	C
php_mysqli.dll!zif_mysqli_poll(int ht, _zval_struct * return_value, _zval_struct * * return_value_ptr, _zval_struct * this_ptr, int return_value_used, void * * * tsrm_ls) Line 800	C

As there in xp_socket.c around line 429 is

*(int*)ret = sock->socket

On x64 windows int is 32 bit, pointer and SOCKET (so php_socket_t) are 64 bit. As one can see, the code is very tricky in that case :)

But the big joke is, that at the other 3-4 places similar code works. Unfortunately earlier i didn't realize the similarity you've pointed to. Maybe that thing should be fixed globally then, as the basic issue on windows is casting int (descritors) vs. SOCKET, which are different things using different APIs. Using SOCKET as descriptor might work but is rather an exception, windows needs two different select()s for those. 

Best regards

Anatol
 [2013-12-05 09:23 UTC] ab@php.net
-Assigned To: mysql +Assigned To: ab
 [2013-12-13 15:12 UTC] ab@php.net
-Status: Assigned +Status: Closed
 [2013-12-13 15:12 UTC] ab@php.net
fixed with da62fd5ed824bafc4dc3e90278c3d57d8e74cbe1
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 16 04:02:11 2014 UTC