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
 [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

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

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-2019 The PHP Group
All rights reserved.
Last updated: Thu Dec 12 06:01:24 2019 UTC