php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #59405 Segmentation fault on null values on ibm db2
Submitted: 2010-09-08 09:46 UTC Modified: 2010-09-16 09:04 UTC
Votes:15
Avg. Score:4.6 ± 1.0
Reproduced:15 of 15 (100.0%)
Same Version:2 (13.3%)
Same OS:4 (26.7%)
From: tuomaksen dot spammiposti at gmail dot com Assigned:
Status: Open Package: PDO_ODBC (PECL)
PHP Version: 5.3.2 OS: Linux (Ubuntu 10.04.1)
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: tuomaksen dot spammiposti at gmail dot com
New email:
PHP Version: OS:

 

 [2010-09-08 09:46 UTC] tuomaksen dot spammiposti at gmail dot com
Description:
------------
I'm trying to use a remote IBM DB2 database with IBM iSeriesAccess ODBC driver (version 6.1.0-1.2) from a Linux server. I noticed that php segfaults when it fetches a row that contains a null value.

I have tested the query shown in the code with unixODBC isql-tool (using iSeriesAccess driver) and with php's ibm_db2 -functions (using commercial DB2 Connect), the query works perfectly in these apps. Segmentation fault only appears using PDO_ODBC.

Also noticed that this query works ok in PDO_ODBC when using MS-SQL database.

Reproduce code:
---------------
#!/usr/bin/php
<?php
$db = new PDO('odbc:db2','db2inst1','db2pwd');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT 
		STTYNO AS ID,
		CASE WHEN STRAPV > 0 
		THEN 
			STRAPV
		ELSE 
			NULL 
		END AS NUM 
	FROM S36DB.PROJECTS";
$result = $db->query($sql);
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
	var_dump($row);
}

Expected result:
----------------
Output:
array(2) {
  ["ID"]=>
  string(2) "57"
  ["NUM"]=>
  string(5) "10102"
}
array(2) {
  ["ID"]=>
  string(2) "60"
  ["NUM"]=>
  string(5) "10102"
}
array(2) {
  ["ID"]=>
  string(2) "61"
  ["NUM"]=>
  string(5) "10102"
}
array(2) {
  ["ID"]=>
  string(2) "63"
  ["NUM"]=>
  NULL
}
array(2) {
  ["ID"]=>
  string(2) "65"
  ["NUM"]=>
  string(5) "10102"
}

Actual result:
--------------
Output:
array(2) {
  ["ID"]=>
  string(2) "57"
  ["NUM"]=>
  string(5) "10102"
}
array(2) {
  ["ID"]=>
  string(2) "60"
  ["NUM"]=>
  string(5) "10102"
}
array(2) {
  ["ID"]=>
  string(2) "61"
  ["NUM"]=>
  string(5) "10102"
}
Segmentation fault

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-09-16 07:39 UTC] tuomaksen dot spammiposti at gmail dot com
Ran the test script in gdb:

$ gdb /usr/bin/php
(gdb) run test.php
<removed some result rows>
array(2) {
  ["ID"]=>
  string(2) "61"
  ["NUM"]=>
  string(5) "10102"
}

Program received signal SIGSEGV, Segmentation fault.
memcpy () at ../sysdeps/x86_64/memcpy.S:513
513     ../sysdeps/x86_64/memcpy.S: No such file or directory.
        in ../sysdeps/x86_64/memcpy.S
(gdb) bt
#0  memcpy () at ../sysdeps/x86_64/memcpy.S:513
#1  0x0000000000678788 in _estrndup ()
#2  0x00007fffe75cbce0 in ?? () from /usr/lib/php5/20090626/pdo.so
#3  0x00007fffe75cec83 in ?? () from /usr/lib/php5/20090626/pdo.so
#4  0x00007fffe75cff0b in ?? () from /usr/lib/php5/20090626/pdo.so
#5  0x00007ffff427ef2a in xdebug_execute_internal (current_execute_data=0x7ffff7e78068, return_value_used=1)
    at /build/buildd/xdebug-2.0.5/build-php5/xdebug.c:1631
#6  0x00000000006e5f36 in ?? ()
#7  0x00000000006bd400 in execute ()
#8  0x00007ffff427eb9e in xdebug_execute (op_array=0x10a4b90) at /build/buildd/xdebug-2.0.5/build-php5/xdebug.c:1562
#9  0x000000000069512d in zend_execute_scripts ()
#10 0x0000000000640d98 in php_execute_script ()
#11 0x0000000000726236 in ?? ()
#12 0x00007ffff52a6c4d in __libc_start_main (main=<value optimized out>, argc=<value optimized out>, ubp_av=<value optimized out>, 
    init=<value optimized out>, fini=<value optimized out>, rtld_fini=<value optimized out>, stack_end=0x7fffffffe298) at libc-start.c:226
#13 0x000000000042c639 in _start ()
 [2010-09-16 09:04 UTC] tuomaksen dot spammiposti at gmail dot com
Here is the backtrace without xdebug and with php debug symbols:

(gdb) bt
#0  memcpy () at ../sysdeps/x86_64/memcpy.S:534
#1  0x0000000000678788 in _estrndup (s=0x10a1670 "", length=4294967295) at /usr/include/bits/string3.h:52
#2  0x00007fffe7808ce0 in fetch_value (stmt=0x10a1848, dest=0x10a2208, colno=18332912, type_override=0x1ffe4b1)
    at /build/buildd/php5-5.3.2/ext/pdo/pdo_stmt.c:635
#3  0x00007fffe780bc83 in T.275 (stmt=0x10a1848, return_value=0x0, how=PDO_FETCH_LAZY, ori=33547441, offset=1283556588, return_all=0x1f7e78068)
    at /build/buildd/php5-5.3.2/ext/pdo/pdo_stmt.c:1040
#4  0x00007fffe780cf0b in zim_PDOStatement_fetch (ht=17438940, return_value=0x10a28d8, return_value_ptr=0xfff3bfff, this_ptr=0x1ffe4b1, 
    return_value_used=1283556588) at /build/buildd/php5-5.3.2/ext/pdo/pdo_stmt.c:1316
#5  0x00000000006e611a in zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7e78068) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:313
#6  0x00000000006bd400 in execute (op_array=0x109e800) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104
#7  0x000000000069512d in zend_execute_scripts (type=32767, retval=0x7fffffffbac0, file_count=3) at /build/buildd/php5-5.3.2/Zend/zend.c:1266
#8  0x0000000000640d98 in php_execute_script (primary_file=0x0) at /build/buildd/php5-5.3.2/main/main.c:2288
#9  0x0000000000726236 in main (argc=0, argv=0x1) at /build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1196
 [2011-05-30 10:17 UTC] pratap_sms at yahoo dot com
Any plans to fix this.
 [2011-07-29 08:24 UTC] mail at tomsommer dot dk
A fix would be nice, yes.
 [2012-09-19 15:50 UTC] rufflesnet at gmail dot com
I have this problem on RHEL 6.1 with PHP 5.3.3 if it helps.
 [2012-10-19 12:26 UTC] tuomas dot angervuori at gmail dot com
This bug might be a 64bit issue only. At least so far I haven't managed to get 
segmentation fault on a 32bit server.

(Note also similar bugs #54007 and #46473)
 [2013-06-26 14:27 UTC] brandonkirsch at gmail dot com
I am very familiar with this problem - IT IS NOT A BUG IN PHP.

64-bit IBM iSeriesAccess ODBC drivers are built against an antiquated definition of what 64-bit ODBC should be. Instead, the IBM drivers use 32-bit values in places where 64-bits should be used.

The end result is that a 32-bit value ("-1" to represent NULL) is interpreted by 64-bit PHP as a large number, causing it to read an invalid memory address and therefore segfault.

You can ask IBM for a better ODBC driver, but they ignored us when we tried.

I have a custom patch for php_odbc.c that "fixes" the problem by hacking up PHP ODBC bindings to treat all ODBC SQL_NULL_DATA values as 32-bit. There are small potential downsides that can occur if you use this patch with a real 64-bit ODBC driver AND you try to access fields > 4GB.

http://www.perceptionilluminates.com/php/php_odbc.c -- It's antiquated (PHP 5.2.17) but it is also well commented, so you can port the hack to a modern version if you'd like.
 [2014-01-31 20:31 UTC] openam at gmail dot com
IBM has released a new Access Client Solutions Product, which appears to correct this problem. They have a post that discusses the improvements over iSeries Access for Linux (http://www.ibm.com/developerworks/ibmi/library/i-ibmi-access-client-solutions-linux/index.html).

You can visit the IBM i Access page at http://www-03.ibm.com/systems/power/software/i/access/solutions.html.
You don't need to install the entire ACS client just the Linux application package.

Here is a document on Obtaining Access Client Solutions (http://www-01.ibm.com/support/docview.wss?uid=nas8N1010355). The document does note that "at this time, you must be entitled to V6R1 or V7R1 IBM i OS." They did require a login and additional customer information.
 [2016-08-09 11:25 UTC] greenleaf123 at fastmail dot fm
I'm having same symptoms accessing a "local" db2 (Express-C) database on debian 8 (jessie) 64 bit:

php (PHP 5.6.20-0+deb8u1) crashes on null values.

Stack trace:
#0  __memcpy_sse2_unaligned ()
    at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:116
#1  0x00000000008553a8 in _estrndup (s=0x7ffff7fdf010 "data from line before", 
    length=4294967295, 
    __zend_filename=0x7ffff60f3c68 "/compile/php/php-src/ext/pdo/pdo_stmt.c", __zend_lineno=641, __zend_orig_filename=0x0, 
    __zend_orig_lineno=0)
    at /compile/php/php-src/Zend/zend_alloc.c:2655
#2  0x00007ffff60ea7bb in fetch_value (stmt=0x7ffff7fe2900, 
    dest=0x7fffec6f65b8, colno=2, type_override=0x0)
    at /compile/php/php-src/ext/pdo/pdo_stmt.c:641
#3  0x00007ffff60ebd49 in do_fetch (stmt=0x7ffff7fe2900, do_bind=1, 
    return_value=0x7ffff7fe2660, how=PDO_FETCH_BOTH, 
    ori=PDO_FETCH_ORI_NEXT, offset=0, return_all=0x0)
    at /compile/php/php-src/ext/pdo/pdo_stmt.c:1034
#4  0x00007ffff60ed6fb in zim_PDOStatement_fetchAll (ht=0, 
    return_value=0x7ffff7fe2810, return_value_ptr=0x7ffff7fa74a0, 
    this_ptr=0x7ffff7fe4a00, return_value_used=1)
    at /compile/php/php-src/ext/pdo/pdo_stmt.c:1519
#5  0x00000000008d3123 in zend_do_fcall_common_helper_SPEC (
    execute_data=0x7ffff7fa7b78)
    at /compile/php/php-src/Zend/zend_vm_execute.h:558


It may be a 32 bit vs 64 bit problem, yet as isql and even a self compiled (64 bit) odbc program work fine there seems to be a way to make it work (like SQLBindParameter vs. SQLGetData).

While the modified version http://www.perceptionilluminates.com/php/php_odbc.c may work around the issue (not tried), I'd suggest the issue to be addressed in odbc_stmt_get_col (ext/pdo_odbc/odbc_stmt.c).

odbc_stmt_get_col has accesses on data hidden in driver_data (I don't know enough on odbc programming to judge if these column accesses are "allowed" at all). One line is comparing "fetched_len == SQL_NULL_DATA" which indeed isn't working with the given values (fetched_len = 0xffffffff).
 [2016-08-09 16:40 UTC] greenleaf123 at fastmail dot fm
Ok, I have to correct myself: Neither isql nor my self compiled program work properly:
- isql is repeating previous data instead of "nullifing" the data correctly
- self compiled program only works because of initializing data properly - length of data returned by SQLGetData is indeed wrong.

For DB2 on z/OS I've found the following regarding the pointer to length of data in SQLGetData:
"For 64-bit applications, the data type SQLINTEGER, which was used in previous versions of DB2, is still valid. However, for maximum application portability, using SQLLEN is recommended."
Source: https://www.ibm.com/support/knowledgecenter/SSEPEK_11.0.0/odbc/src/tpc/db2z_fngetdata.html

I haven't found that notice for DB2-LUW, though. Still it seems to work that way.

I suggest the following:
- When SQLGetData returns SQL_SUCCESS and the length returned is 0xffffffff (and larger as buffer size) it is to be interpreted as SQL_NULL_DATA.
- When SQLGetData returns SQL_SUCCESS_WITH_INFO and the length returned is 0xffffffff (and larger as buffer size) it is *not* to be mistaken as SQL_NULL_DATA.
 [2023-06-20 06:01 UTC] gooddharma9 at gmail dot com
Web Tech Blogs are sharing latest news about about tech, gadets, digital marketing, seo, smo, ppc, web development, web design etc. More info to visit: (https://webtechblogs.com)github.com
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Nov 26 21:01:32 2024 UTC