php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77935 Crash in mysqlnd_fetch_stmt_row_cursor when calling an SP with a cursor
Submitted: 2019-04-24 14:03 UTC Modified: 2020-12-18 09:34 UTC
From: rh at tfli dot co dot uk Assigned: nikic (profile)
Status: Closed Package: MySQLi related
PHP Version: 7.3.4 OS: Windows 10 (64Bit)
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: rh at tfli dot co dot uk
New email:
PHP Version: OS:

 

 [2019-04-24 14:03 UTC] rh at tfli dot co dot uk
Description:
------------
Good Afternoon,

When you connect to a Maria Server (10.3) using the mysqli extension, then if you prepare a statement which calls a stored procedure; where that stored procedure uses opens a cursor on the server and returns a result set, when you try and fetch the result set as a mysqli_result, PHP will crash with a access violation.

- I assume this will also apply to MySQL.
- If you try and fetch() the result set from the mysqli_stmt object, you get a warning about packets being out of order and no data. I believe the cause is the same problem.
- The problem seems to be related that the COM_STMT_EXECUTE response has a server flag marking 'SERVER_STATUS_CURSOR_EXISTS' as Set when a cursor is used in the stored procedure. This flag is meant to be used with COM_STMT_FETCH, and I believe this to be a server bug (which will be reported to MariaDB as well).
- When that flag is set and you try to call a function like fetch_all on a mysqli_result retrieved from the mysqli_stmt; when mysqlnd_fetch_stmt_row_cursor is called, param which is passed in is not the mysqli_stmt as expected (WinDbg revealed for me that it was the PHP.ini file).
- In my tests, the bytes that were thought to be the statement's status were 0, so it thought the status was MYSQLND_STMT_INITTED. However, when it tried to set the connection error to CR_COMMANDS_OUT_OF_SYNC, what was thought to be the connection pointed to an invalid memory location, throwing the access violation.

Can the SERVER_STATUS_CURSOR_EXISTS be ignored in the COM_STMT_EXECUTE response?

Test script:
---------------
/* SQL Script:
DELIMITER $$

CREATE
    PROCEDURE `testSp`()
	BEGIN
		DECLARE `cur` CURSOR FOR SELECT 1;
		OPEN `cur`;
		CLOSE `cur`;
		SELECT 1;
	END$$

DELIMITER ; */
<?PHP
$dbHost = '';
$dbUsername = '';
$dbPassword = '';
$dbName = "";
$dbConn			= new mysqli($dbHost, $dbUsername, $dbPassword, $dbName);
$prepopReturnStmt		= $dbConn->prepare("CALL `testSp`()");
$prepopReturnStmt->execute();
$mysqliresult	= $prepopReturnStmt->get_result();
var_dump($mysqliresult); // This will work, and print $num_rows as 0, but $field_count as 1. $type is incorrect (1 instead of 0)
$result			= $mysqliresult->fetch_assoc(); // This causes the crash
var_dump($result);

Expected result:
----------------
class mysqli_result#3 (5) {
  public $current_field =>
  int(0)
  public $field_count =>
  int(1)
  public $lengths =>
  NULL
  public $num_rows =>
  int(1)
  public $type =>
  int(0)
}
D:\WebServer\htdocs\testScript2.php:12:
array(1) {
  [1] =>
  int(1)
}

Actual result:
--------------
class mysqli_result#3 (5) {
  public $current_field =>
  int(0)
  public $field_count =>
  int(1)
  public $lengths =>
  NULL
  public $num_rows =>
  int(0)
  public $type =>
  int(1)
}

/* Backtrace from Debug Diagnostic Tool */
php7ts!mysqlnd_fetch_stmt_row_cursor+69 [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\ext\mysqlnd\mysqlnd_ps.c @ 1044]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\ext\mysqlnd\mysqlnd_ps.c @ 1044 
php7ts!mysqlnd_mysqlnd_res_fetch_row_pub+2d [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\ext\mysqlnd\mysqlnd_result.c @ 1245]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\ext\mysqlnd\mysqlnd_result.c @ 1245 
php7ts!mysqlnd_mysqlnd_res_fetch_into_pub+59 [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\ext\mysqlnd\mysqlnd_result.c @ 1730 + 1f]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\ext\mysqlnd\mysqlnd_result.c @ 1730 + 1f 
php_mysqli!php_mysqli_fetch_into_hash+103 [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\ext\mysqli\mysqli.c @ 1261]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\ext\mysqli\mysqli.c @ 1261 
php_xdebug_2_7_1_7_3_vc15_x86_64+6f3a    
php7ts!ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER+19a [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\zend\zend_vm_execute.h @ 1116 + 6]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\zend\zend_vm_execute.h @ 1116 + 6 
php7ts!execute_ex+5f [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\zend\zend_vm_execute.h @ 55334 + f]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\zend\zend_vm_execute.h @ 55334 + f 
php_xdebug_2_7_1_7_3_vc15_x86_64+6760    
php7ts!zend_execute+1a8 [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\zend\zend_vm_execute.h @ 60882]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\zend\zend_vm_execute.h @ 60882 
php7ts!zend_execute_scripts+b9 [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\zend\zend.c @ 1569]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\zend\zend.c @ 1569 
php7ts!php_execute_script+261 [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\main\main.c @ 2632]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\main\main.c @ 2632 
php!do_cli+aa0 [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\sapi\cli\php_cli.c @ 998]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\sapi\cli\php_cli.c @ 998 
php!main+6f8 [c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\sapi\cli\php_cli.c @ 1389 + 5]   c:\php-snap-build\php73\vc15\x64\php-7.3.4-ts\sapi\cli\php_cli.c @ 1389 + 5 
php!__scrt_common_main_seh+10c [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288 + 22]   f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288 + 22 
kernel32!BaseThreadInitThunk+14    
ntdll!RtlUserThreadStart+21

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-07-24 09:42 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2020-07-24 09:42 UTC] cmb@php.net
The segfault also happens with MySQL 5.6.44 and PHP 7.4.
 [2020-12-18 09:34 UTC] nikic@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: nikic
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 10 14:01:27 2024 UTC