Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs #193

Closed
wants to merge 5 commits into from

6 participants

Brandon Kirsch Anthony Ferrara David Soria Parra Felipe Pena Account for PHP Pull Requests Adam Harvey
Brandon Kirsch

Fix for https://bugs.php.net/bug.php?id=61387

Changed conditional @ php_odbc.c:1774 to include the check:

     && Z_TYPE_P(tmp) != IS_NULL

This prevents a potential segfault on 1775 when zend_hash_update is called with Z_STR*(tmp) args.

Example script ("fetch_array.php"):

<?php
$c = odbc_connect('Driver=SQL Server Native Client 11.0;server=xxx;uid=xxx;pwd=xxx;Database=xxx','','');
$e = odbc_exec($c, 'SELECT NULL'); // The result set contains an unamed column with a NULL value
$row = odbc_fetch_array($e); // segfault when retrieved
?>

Backtrace:

Program received signal SIGSEGV, Segmentation fault.
zend_inline_hash_func (nKeyLength=, arKey=0x0) at /usr/src/php_fix/php-src/Zend/zend_hash.h:283
283 case 1: hash = ((hash << 5) + hash) + *arKey++; break;

#0 zend_inline_hash_func (nKeyLength=, arKey=0x0) at /usr/src/php_fix/php-src/Zend/zend_hash.h:283
#1 _zend_hash_add_or_update (ht=0xfce7d0, arKey=0x0, nKeyLength=1, pData=0x7fffffffab80, nDataSize=8, pDest=0x0, flag=1) at /usr/src/php_fix/php-src/Zend/zend_hash.c:218
#2 0x00000000005752af in php_odbc_fetch_hash (ht=, return_value=0xfcd038, result_type=2, return_value_ptr=, this_ptr=,
return_value_used=) at /usr/src/php_fix/php-src/ext/odbc/php_odbc.c:1775

BRANDON KIRSCH added some commits
BRANDON KIRSCH php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs
php_odbc.c:1774 Changed the conditional to include the check:

	 && Z_TYPE_P(tmp) != IS_NULL

This prevents a potential segfault on 1775 where zend_hash_update is
called with Z_STR*(tmp) args.

Fixes Bug https://bugs.php.net/bug.php?id=61387
d0d978b
BRANDON KIRSCH Merge branch 'PHP-5.3' into PHP-5.4
* PHP-5.3:
  php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs
1a72814
BRANDON KIRSCH Merge branch 'PHP-5.4'
* PHP-5.4:
  php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs
1f11dde
Brandon Kirsch

Fix for https://bugs.php.net/bug.php?id=61387

php_odbc_fetch_hash() / odbc_fetch_array()

Some ODBC Drivers (SQL Server Native Client) cause a segfault when using odbc_fetch_array() with certain result sets containing NULLs.

Example script ("fetch_array.php"):

<?php
$c = odbc_connect('Driver=SQL Server Native Client 11.0;server=xxx;uid=xxx;pwd=xxx;Database=xxx','','');
$e = odbc_exec($c, 'SELECT NULL'); // The result set contains an unamed column with a NULL value
$row = odbc_fetch_array($e); // segfault when retrieved
?>

Backtrace:

Program received signal SIGSEGV, Segmentation fault.
zend_inline_hash_func (nKeyLength=, arKey=0x0) at /usr/src/php_fix/php-src/Zend/zend_hash.h:283
283 case 1: hash = ((hash << 5) + hash) + *arKey++; break;

#0 zend_inline_hash_func (nKeyLength=, arKey=0x0) at /usr/src/php_fix/php-src/Zend/zend_hash.h:283
#1 _zend_hash_add_or_update (ht=0xfce7d0, arKey=0x0, nKeyLength=1, pData=0x7fffffffab80, nDataSize=8, pDest=0x0, flag=1) at /usr/src/php_fix/php-src/Zend/zend_hash.c:218
#2 0x00000000005752af in php_odbc_fetch_hash (ht=, return_value=0xfcd038, result_type=2, return_value_ptr=, this_ptr=,
return_value_used=) at /usr/src/php_fix/php-src/ext/odbc/php_odbc.c:1775

Anthony Ferrara

Looks good to me. The only thing I'd suggest is targeting the PR against 5.3, so that it can be merged up easier.

Other than that, the fix seems good (fixes a logic error where the type of the zval isn't the same)...

ext/odbc/php_odbc.c
@@ -1765,7 +1765,7 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type)
1765 1765 if (result_type & ODBC_NUM) {
1766 1766 zend_hash_index_update(Z_ARRVAL_P(return_value), i, &tmp, sizeof(zval *), NULL);
1767 1767 } else {
1768   - if (!*(result->values[i].name)) {
  1768 + if (!*(result->values[i].name) && Z_TYPE_P(tmp) != IS_NULL) {
2

Should this be Z_TYPE_P(tmp) == IS_STRING, rather than not IS_NULL? From context, it's obvious that the only two possible zval types for tmp are IS_STRING and IS_NULL, but this strikes me as a potential gotcha if the function is changed down the track to return more native PHP types for numeric values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
BRANDON KIRSCH added some commits
BRANDON KIRSCH php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs
php_odbc.c:1774 Changed the conditional to include the check:

	 && Z_TYPE_P(tmp) == IS_STRING

This avoids a potential segfault on 1775 where ZSTR_ macros are used
when the ZVAL is sometimes NULL.
383fcb3
BRANDON KIRSCH Merge branch 'PHP-5.3'
* PHP-5.3:
  php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs
1f55a42
Brandon Kirsch

Original patch used != IS_NULL. Per suggestion, changed to == IS_STRING.

David Soria Parra
Owner

Please don't submit merges. Pull requests should only contain the actual changes. The PR should be for the lowest branch to which the changes apply (PHP-5.3 in this case).

So if you don't squash d0d978b and 383fcb3 together and don't include the merges (we will do the merging for you :)).

Anyway, thanks a lot for the patches. At a first glance they look okay and I am looking into merging them.

Brandon Kirsch
Felipe Pena

I've pushed your changes manually, thanks!

Account for PHP Pull Requests
Collaborator

Comment on behalf of felipe at php.net:

Done.

Account for PHP Pull Requests php-pulls closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 5 unique commits by 1 author.

Sep 13, 2012
BRANDON KIRSCH php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs
php_odbc.c:1774 Changed the conditional to include the check:

	 && Z_TYPE_P(tmp) != IS_NULL

This prevents a potential segfault on 1775 where zend_hash_update is
called with Z_STR*(tmp) args.

Fixes Bug https://bugs.php.net/bug.php?id=61387
d0d978b
BRANDON KIRSCH Merge branch 'PHP-5.3' into PHP-5.4
* PHP-5.3:
  php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs
1a72814
BRANDON KIRSCH Merge branch 'PHP-5.4'
* PHP-5.4:
  php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs
1f11dde
BRANDON KIRSCH php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs
php_odbc.c:1774 Changed the conditional to include the check:

	 && Z_TYPE_P(tmp) == IS_STRING

This avoids a potential segfault on 1775 where ZSTR_ macros are used
when the ZVAL is sometimes NULL.
383fcb3
BRANDON KIRSCH Merge branch 'PHP-5.3'
* PHP-5.3:
  php_odbc_fetch_hash() Fixed a segfault when fetching certain SQL NULLs
1f55a42
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 1 addition and 1 deletion. Show diff stats Hide diff stats

  1. +1 1  ext/odbc/php_odbc.c
2  ext/odbc/php_odbc.c
@@ -1765,7 +1765,7 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type)
1765 1765 if (result_type & ODBC_NUM) {
1766 1766 zend_hash_index_update(Z_ARRVAL_P(return_value), i, &tmp, sizeof(zval *), NULL);
1767 1767 } else {
1768   - if (!*(result->values[i].name)) {
  1768 + if (!*(result->values[i].name) && Z_TYPE_P(tmp) == IS_STRING) {
1769 1769 zend_hash_update(Z_ARRVAL_P(return_value), Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)+1, &tmp, sizeof(zval *), NULL);
1770 1770 } else {
1771 1771 zend_hash_update(Z_ARRVAL_P(return_value), result->values[i].name, strlen(result->values[i].name)+1, &tmp, sizeof(zval *), NULL);

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.