php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38759 PDO sqlite2 empty query causes segfault
Submitted: 2006-09-09 00:50 UTC Modified: 2006-09-09 14:36 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: jcd+php at psu dot edu Assigned:
Status: Closed Package: SQLite related
PHP Version: 5.1.6 OS: Solaris 9 / Ubuntu Linux 6.06
Private report: No CVE-ID:
 [2006-09-09 00:50 UTC] jcd+php at psu dot edu
Description:
------------
Empty, whitespace and/or comments only query strings passed into the query method of a PDO object for a 'sqlite2' database appear to cause segmentation faults.  PDO 'sqlite' (SQLite 3) objects appear immune as does the older sqlite extention (sqlite_query()).

The function pdo_sqlite2_stmt_execute() in
ext/sqlite/pdo_sqlite2.c does not appear to catch a case when sqlite_compile() returns SQLITE_OK but sets the sqlite virtual machine pointer to NULL.  This seems to occur for empty query strings (0 length, whitespace and/or comments).  When passed unchecked into sqlite_step(), as it appears to be in pdo_sqlite2_stmt_execute(), sqlite_step() attempts to dereference the pointer, causing a segmentation fault.  The equivalent function (sqlite_query()) in ext/sqlite/sqlite.c appears to catch this.

This occurs on both:
- Solaris 9, Sun Forte Developer 7 C compiler
- Ubuntu Linux 6.06, gcc 4.0.3 (Ubuntu 4.0.3-1ubuntu5)

Using both PHP versions:
- php-5.1.6
- php5.2-200609072030

The shorter configure line (ubuntu) was:
./configure \
--with-apxs2=/usr/bin/apxs2 \
--prefix=/usr/local/php-5.1.6 \
--with-pdo-sqlite \
--with-sqlite \
--with-libxml-dir=/usr

I triggered it in both mod_php + Apache (1 and 2) and on the command line.  The traces are for the cli.

The solaris version had some php.ini customizations, the ubuntu install had none.

Reproduce code:
---------------
<?php

$dbh = new PDO('sqlite2:pdo_sqlite2');

$dbh->query(" ");

?>

Expected result:
----------------
Not crash.  Either return an error to indicate the fact that the query was empty or do nothing.  

I found that the patch at 
http://www.personal.psu.edu/jcd/patches/php-5.1.6_pdo_sqlite2_empty_query.patch
fixed the segfaults for me on both platforms I tested.  


Actual result:
--------------
I can reproduce a segfault with every try.  With my patch, I have yet to trigger a crash.

solaris9$ pstack /export/cores/core.snail.0.php.14111
core '/export/cores/core.snail.0.php.14111' of 14111:   /export/ladmin/phase2.build4/php/bi
n/php pdo_sqlite2_bugtest.php
 00586430 sqlite_step (0, ff4558, ff4550, ff4554, ffbfe87c, 11828) + 40
 00541e64 pdo_sqlite2_stmt_execute (ff0e08, d475d8, ff0e5c, 30000000, 3000, 0) + 1b4
 003f789c zif_PDO_query (1, feceb8, 0, fece68, 0, 0) + 31c
 0086397c zend_do_fcall_common_helper_SPEC (ffbfebb0, fece90, 5, 0, 0, 0) + 5cc
 00864238 ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (ffbfebb0, 0, ffffffff, 5, 0, ffbfea85) + 38
 00863220 execute  (feeb60, f00d50, 4e, ffbfecf4, 4, 0) + 2c8
 008064ac zend_execute_scripts (8, 0, 3, 0, ffbff3b0, 0) + 1cc
 00732244 php_execute_script (ffbff3b0, d70819, ffbff36c, 0, 70, 2d) + 3c4
 008e2b48 main     (2, ffbff444, ffbff450, da2400, 0, 0) + 1580
 001e06c8 _start   (0, 0, 0, 0, 0, 0) + 108

ubuntu6.06$ gdb /usr/local/php-5.1.6/bin/php core
GNU gdb 6.4-debian
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i68
6/cmov/libthread_db.so.1".

Core was generated by `/usr/local/php-5.1.6/bin/php -r $h=new PDO("sqlite2:db/sqlite.db");$
h->query("'.
Program terminated with signal 11, Segmentation fault.

warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/tls/i686/cmov/libcrypt.so.1...done.
Loaded symbols for /lib/tls/i686/cmov/libcrypt.so.1
Reading symbols from /lib/tls/i686/cmov/librt.so.1...done.
Loaded symbols for /lib/tls/i686/cmov/librt.so.1
Reading symbols from /lib/tls/i686/cmov/libresolv.so.2...done.
Loaded symbols for /lib/tls/i686/cmov/libresolv.so.2
Reading symbols from /lib/tls/i686/cmov/libm.so.6...done.
Loaded symbols for /lib/tls/i686/cmov/libm.so.6
Reading symbols from /lib/tls/i686/cmov/libnsl.so.1...done.
Loaded symbols for /lib/tls/i686/cmov/libnsl.so.1
Reading symbols from /usr/lib/libz.so.1...done.
Loaded symbols for /usr/lib/libz.so.1
Reading symbols from /usr/lib/libxml2.so.2...done.
Loaded symbols for /usr/lib/libxml2.so.2
Reading symbols from /lib/tls/i686/cmov/libdl.so.2...done.
Loaded symbols for /lib/tls/i686/cmov/libdl.so.2
Reading symbols from /lib/tls/i686/cmov/libpthread.so.0...done.
Loaded symbols for /lib/tls/i686/cmov/libpthread.so.0
Reading symbols from /lib/tls/i686/cmov/libc.so.6...done.
Loaded symbols for /lib/tls/i686/cmov/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  sqlite_step (pVm=0x0, pN=0x84a9abc, pazValue=0x84a9ab4, pazColName=0x84a9ab8)
    at /usr/local/src/jcd/php-5.1.6/ext/sqlite/libsqlite/src/vdbe.c:117
117       if( p->magic!=VDBE_MAGIC_RUN ){
(gdb) bt
#0  sqlite_step (pVm=0x0, pN=0x84a9abc, pazValue=0x84a9ab4, pazColName=0x84a9ab8)
    at /usr/local/src/jcd/php-5.1.6/ext/sqlite/libsqlite/src/vdbe.c:117
#1  0x08161528 in pdo_sqlite2_stmt_execute (stmt=0x84a991c, tsrm_ls=0x83a0018)
    at /usr/local/src/jcd/php-5.1.6/ext/sqlite/pdo_sqlite2.c:102
#2  0x080edbfa in zif_PDO_query (ht=1, return_value=0x84a59ec, return_value_ptr=0x0,
    this_ptr=0x84a5a2c, return_value_used=0, tsrm_ls=0x83a0018)
    at /usr/local/src/jcd/php-5.1.6/ext/pdo/pdo_dbh.c:985
#3  0x0826ed05 in zend_do_fcall_common_helper_SPEC (execute_data=0xbfbf276c,
    tsrm_ls=0x83a0018) at zend_vm_execute.h:200
#4  0x0826e23c in execute (op_array=0x84a607c, tsrm_ls=0x83a0018) at zend_vm_execute.h:92
#5  0x08246edd in zend_eval_string (
    str=0xbfbf3669 "$h=new PDO(\"sqlite2:db/sqlite.db\");$h->query(\" \");",
    retval_ptr=0x0, string_name=0x0, tsrm_ls=0x83a0018)
    at /usr/local/src/jcd/php-5.1.6/Zend/zend_execute_API.c:1116
#6  0x0824705c in zend_eval_string_ex (str=0x0, retval_ptr=0x0, string_name=0x0,
    handle_exceptions=1, tsrm_ls=0x83a0018)
    at /usr/local/src/jcd/php-5.1.6/Zend/zend_execute_API.c:1150
#7  0x082e60b6 in main (argc=3, argv=0xbfbf2b54)
    at /usr/local/src/jcd/php-5.1.6/sapi/cli/php_cli.c:1132

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-09-09 10:59 UTC] tony2001@php.net
This is actually SQLite problem, but I agree, a workaround is required.
Fixed in 5_2 and HEAD.
 [2006-09-09 14:36 UTC] jcd+php at psu dot edu
Thanks for committing this.  

It did seem pretty murky if this was more an SQLite or PHP issue due to the language used for sqlite_step() in the version 2 API docs on http://sqlite.org/c_interface.html, section 2.2.  Though, I agree functions should check pointer arguments before dereference.  Thanks again!
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 20:01:57 2014 UTC