Bug #73210 [Ver->Csd]: Segfault with stmt read only cursor and get_result due to double closing
| From: | nikic@php.net | Date: | Fri, 18 Dec 2020 09:33:36 +0000 |
| Subject: | Bug #73210 [Ver->Csd]: 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-231145@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
Updated by: nikic@php.net
Reported by: richard dot fussenegger at trivago dot com
Summary: Segfault with stmt read only cursor and get_result
due to double closing
-Status: Verified
+Status: Closed
Type: Bug
Package: MySQLi related
Operating System: Irrelevant
PHP Version: Irrelevant
-Assigned To:
+Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
No longer crashes on 7.4 HEAD, presumably fixed by https://github.com/php/php-src/commit/bc166844e37a6e1531a18dc0916fbe508152fc6c
or related changes. (Does valgrind on 7.3.)
Previous Comments:
------------------------------------------------------------------------
[2019-08-08 07:01:49] cmb@php.net
@tekiela246, your issue is actually a duplicate of bug #72413.
------------------------------------------------------------------------
[2019-08-01 12:50:32] cmb@php.net
> For PHP 7.2, the segfault already happens when the result is
> freed
No, nonsense. It's the double free described by @nikic.
------------------------------------------------------------------------
[2019-08-01 12:43:56] cmb@php.net
For PHP 7.2, the segfault already happens when the result is
freed:
php7_debug.dll!mysqlnd_mysqlnd_res_free_result_internal_pub(st_mysqlnd_res * result) Line 348
(c:\php-sdk\phpdev\vc15\x64\php-src-7.2\ext\mysqlnd\mysqlnd_result.c:348)
php7_debug.dll!mysqlnd_mysqlnd_stmt_free_stmt_result_pub(st_mysqlnd_stmt * const s) Line 2131
(c:\php-sdk\phpdev\vc15\x64\php-src-7.2\ext\mysqlnd\mysqlnd_ps.c:2131)
php7_debug.dll!mysqlnd_mysqlnd_stmt_free_stmt_content_pub(st_mysqlnd_stmt * const s) Line 2175
(c:\php-sdk\phpdev\vc15\x64\php-src-7.2\ext\mysqlnd\mysqlnd_ps.c:2175)
php7_debug.dll!mysqlnd_mysqlnd_stmt_close_on_server_priv(st_mysqlnd_stmt * const s, unsigned
char implicit) Line 2261 (c:\php-sdk\phpdev\vc15\x64\php-src-7.2\ext\mysqlnd\mysqlnd_ps.c:2261)
php7_debug.dll!mysqlnd_mysqlnd_stmt_dtor_pub(st_mysqlnd_stmt * const s, unsigned char implicit)
Line 2285 (c:\php-sdk\phpdev\vc15\x64\php-src-7.2\ext\mysqlnd\mysqlnd_ps.c:2285)
php7_debug.dll!zif_mysqli_stmt_close(_zend_execute_data * execute_data, _zval_struct *
return_value) Line 2064 (c:\php-sdk\phpdev\vc15\x64\php-src-7.2\ext\mysqli\mysqli_api.c:2064)
php7_debug.dll!ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER(_zend_execute_data * execute_data) Line
908 (c:\php-sdk\phpdev\vc15\x64\php-src-7.2\Zend\zend_vm_execute.h:908)
php7_debug.dll!execute_ex(_zend_execute_data * ex) Line 59739
(c:\php-sdk\phpdev\vc15\x64\php-src-7.2\Zend\zend_vm_execute.h:59739)
php7_debug.dll!zend_execute(_zend_op_array * op_array, _zval_struct * return_value) Line 63777
(c:\php-sdk\phpdev\vc15\x64\php-src-7.2\Zend\zend_vm_execute.h:63777)
php7_debug.dll!zend_execute_scripts(int type, _zval_struct * retval, int file_count, ...) Line
1499 (c:\php-sdk\phpdev\vc15\x64\php-src-7.2\Zend\zend.c:1499)
php7_debug.dll!php_execute_script(_zend_file_handle * primary_file) Line 2599
(c:\php-sdk\phpdev\vc15\x64\php-src-7.2\main\main.c:2599)
php.exe!do_cli(int argc, char * * argv) Line 1012
(c:\php-sdk\phpdev\vc15\x64\php-src-7.2\sapi\cli\php_cli.c:1012)
php.exe!main(int argc, char * * argv) Line 1403
(c:\php-sdk\phpdev\vc15\x64\php-src-7.2\sapi\cli\php_cli.c:1403)
php.exe!invoke_main() Line 79
(d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:79)
php.exe!__scrt_common_main_seh() Line 288
(d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
php.exe!__scrt_common_main() Line 331
(d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:331)
php.exe!mainCRTStartup() Line 17
(d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:17)
kernel32.dll!00007ffeba257bd4() (Unbekannte Quelle:0)
ntdll.dll!00007ffebadece71() (Unbekannte Quelle:0)
I set a breakpoint on mysqlnd_result.c:1527[1], and did
p result->conn // 0x0000016afac76500
n
p result->conn // 0x0000016afac9c180
@tekiela246, your problem doesn't seem related to this issue,
so please file a new ticket.
[1] <https://github.com/php/php-src/blob/php-7.2.21/ext/mysqlnd/mysqlnd_result.c#L1527>
------------------------------------------------------------------------
[2019-08-01 09:33:22] nikic@php.net
We're freeing the result twice, once directly via free_result and again indirectly via
stmt_close.
We could store a back-reference to the stmt in the result and NULL it when the result if freed, but
that would only solve the problem for the case where free_result is called before stmt_close. For
the reverse case we'd need access to the PHP resource storing the result, which we don't
have.
Possibly the result needs to be refcounted?
------------------------------------------------------------------------
[2019-08-01 09:14:33] nikic@php.net
Confirming original segfault on 7.2 and valgrind errors on newer versions.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=73210
--
Edit this bug report at https://bugs.php.net/bug.php?id=73210&edit=1