Bug #73210 [Com]: Segfault with stmt read only cursor and get_result due to double closing
| From: | tekiela246 at gmail dot com | Date: | Wed, 31 Jul 2019 20:55:30 +0000 |
| Subject: | Bug #73210 [Com]: Segfault with stmt read only cursor and get_result due to double closing | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-222030@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=73210&edit=1
ID: 73210
Comment by: tekiela246 at gmail dot com
Reported by: richard dot fussenegger at trivago dot com
Summary: Segfault with stmt read only cursor and get_result
due to double closing
Status: Open
Type: Bug
Package: MySQLi related
Operating System: Irrelevant
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
I have a similar problem, but I am not sure if it is the same one. I also get a SEGFAULT when I
execute this code:
$mysqli = new mysqli($host, $user, $pass, $db);
$stmtQuery = $mysqli->prepare("SELECT ?, 'name'");
$stmtQuery->bind_result($id, $name);
$stmtQuery->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY);
$stmtQuery->bind_param('i', $i);
$stmtQuery->execute();
$stmtQuery->get_result()->fetch_assoc();
---------
I could not get the proper backtrace. I only have this if it helps:
php7ts!mysqlnd_pfc_free+400
php7ts!mysqlnd_protocol_payload_decoder_factory_free+548
php7ts!mysqlnd_result_buffered_c_init+2c23
php7ts!mysqlnd_result_buffered_c_init+3c2b
php_mysqli+1133
php7ts!php_json_parse+2f8b
php7ts!mysqlnd_protocol_payload_decoder_factory_free+439a
php7ts!mysqlnd_protocol_payload_decoder_factory_free+43f7
php7ts!mysqlnd_result_buffered_c_init+2274
php7ts!mysqlnd_result_buffered_c_init+22b1
php7ts!mysqlnd_pfc_free+2d84
php7ts!ecalloc+b9
php_mysqli!mysqli_objects_new+5a
php_mysqli!mysqli_objects_new+2167
php_mysqli!get_module+7591
php7ts!execute_ex+78
php7ts!zend_execute+124
php7ts!zend_execute+152
php7ts!zend_execute_scripts+96
php7ts!zend_set_timeout+90
Previous Comments:
------------------------------------------------------------------------
[2018-05-04 21:26:00] cmb@php.net
> Patch will be directly provided as GitHub PR.
FTR: <https://github.com/php/php-src/pull/2146>
didn't really
solve the issue.
------------------------------------------------------------------------
[2016-09-30 11:28:04] richard dot fussenegger at trivago dot com
Description:
------------
Getting the result of an executed prepared statement that uses a read only cursor results in a
segfault because the second close call tries to free the internal result on null. It does not matter
which is the first or second close call since stmt gives result a pointer to the result, the one
that calls it first is the one that frees it and the other one accesses null.
The access happens in mysqlnd_res::free_result_internal after the if (result->conn) condition
where result->conn->m is being called. The m might already point to nowhere because the
previous close call already freed it.
Patch will be directly provided as GitHub PR.
Test script:
---------------
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'root', 'keines');
$stmt = $mysqli->prepare('SELECT 1 UNION SELECT 2 UNION SELECT 3');
$stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY);
$stmt->execute();
$result = $stmt->get_result();
// call order does not matter {{{
$result->close();
$stmt->close();
// }}}
$mysqli->close();
Expected result:
----------------
Successful and graceful shutdown of PHP.
Actual result:
--------------
Segfault
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=73210&edit=1