php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78192 SegFault when reuse statement after schema has changed
Submitted: 2019-06-21 09:23 UTC Modified: 2019-06-28 10:40 UTC
From: stanneux at b2pweb dot com Assigned: cmb (profile)
Status: Closed Package: PDO SQLite
PHP Version: 7.2.19 OS: linux Fedora
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: stanneux at b2pweb dot com
New email:
PHP Version: OS:

 

 [2019-06-21 09:23 UTC] stanneux at b2pweb dot com
Description:
------------
This bug occurs on php 7.2.0 and it is not fixed in v7.3.6. The test script has been launched on docker image php:7.2-cli and php:7.3-cli

The test case fail with pdo_sqlite but works fine with SQLite3
No changes set on docker images. The php.ini file is the same.

Test script:
---------------
<?php
$connection = new \PDO('sqlite::memory:');
$connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$connection->query('CREATE TABLE user (id INTEGER PRIMARY KEY NOT NULL, name VARCHAR(255) NOT NULL)');

$stmt = $connection->prepare('INSERT INTO user (id, name) VALUES(:id, :name)');
$stmt->execute([
    'id'   => 10,
    'name' => 'test',
]);

$stmt = $connection->prepare('SELECT * FROM user WHERE id = :id');
$stmt->execute(['id' => 10]);
$stmt->fetchAll(\PDO::FETCH_ASSOC);

$connection->query('ALTER TABLE user ADD new_col VARCHAR(255)');
$stmt->execute(['id' => 10]); // SegFault here


Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-06-21 09:41 UTC] sjon@php.net
-Status: Open +Status: Verified
 [2019-06-21 09:41 UTC] sjon@php.net
this has some interesting behaviour - 7.1 (still) throws a correct exception, 7.2 fails silently and 7.3 / 7.4 segfault
 [2019-06-21 10:00 UTC] cmb@php.net
Stack backtrace:

php7ts_debug.dll!zend_string_release_ex(_zend_string * s, int persistent) Line 284 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend_string.h:284)
php7ts_debug.dll!php_pdo_free_statement(_pdo_stmt_t * stmt) Line 2333 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\ext\pdo\pdo_stmt.c:2333)
php7ts_debug.dll!pdo_dbstmt_free_storage(_zend_object * std) Line 2357 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\ext\pdo\pdo_stmt.c:2357)
php7ts_debug.dll!zend_objects_store_del(_zend_object * object) Line 191 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend_objects_API.c:191)
php7ts_debug.dll!zend_object_destroy_wrapper(_zend_object * obj) Line 96 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend_variables.c:96)
php7ts_debug.dll!rc_dtor_func(_zend_refcounted * p) Line 66 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend_variables.c:66)
php7ts_debug.dll!i_zval_ptr_dtor(_zval_struct * zval_ptr, const char * __zend_filename, const unsigned int __zend_lineno) Line 45 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend_variables.h:45)
php7ts_debug.dll!zval_ptr_dtor(_zval_struct * zval_ptr) Line 112 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend_variables.c:112)
php7ts_debug.dll!_zend_hash_del_el_ex(_zend_array * ht, unsigned int idx, _Bucket * p, _Bucket * prev) Line 1183 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend_hash.c:1183)
php7ts_debug.dll!_zend_hash_del_el(_zend_array * ht, unsigned int idx, _Bucket * p) Line 1206 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend_hash.c:1206)
php7ts_debug.dll!zend_hash_reverse_apply(_zend_array * ht, int(*)(_zval_struct *) apply_func) Line 1778 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend_hash.c:1778)
php7ts_debug.dll!shutdown_destructors() Line 241 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend_execute_API.c:241)
php7ts_debug.dll!zend_call_destructors() Line 1090 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\Zend\zend.c:1090)
php7ts_debug.dll!php_request_shutdown(void * dummy) Line 1878 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\main\main.c:1878)
php.exe!do_cli(int argc, char * * argv) Line 1166 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\sapi\cli\php_cli.c:1166)
php.exe!main(int argc, char * * argv) Line 1389 (c:\php-sdk\phpdev\vc15\x64\php-src-7.3\sapi\cli\php_cli.c:1389)
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)

It seems that after the ALTER TABLE statement, stmt->column_count is updated, but stmt->columns not. The resulting OOB read should be indicated by a memory checker.
 [2019-06-26 09:50 UTC] vquatrevieux at b2pweb dot com
The following pull request has been associated:

Patch Name: Fix bug #78192 PDO SQLite reset columns on schema changed
On GitHub:  https://github.com/php/php-src/pull/4313
Patch:      https://github.com/php/php-src/pull/4313.patch
 [2019-06-28 10:38 UTC] cmb@php.net
Automatic comment on behalf of vquatrevieux@b2pweb.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=05c00a832c7b395398ef8e60edd8a7ec25439861
Log: Fix bug #78192 PDO SQLite SegFault when reuse statement after schema has changed
 [2019-06-28 10:38 UTC] cmb@php.net
-Status: Verified +Status: Closed
 [2019-06-28 10:40 UTC] cmb@php.net
-Assigned To: +Assigned To: cmb
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC