Bug #80460 [NEW]: ODBC doesn't account for SQL_NO_TOTAL indicator, causing segmentation fault

From: Date: Wed, 02 Dec 2020 02:46:36 +0000
Subject: Bug #80460 [NEW]: ODBC doesn't account for SQL_NO_TOTAL indicator, causing segmentation fault
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-230781@lists.php.net to get a copy of this message
From:             mirish at ibm dot com
Operating system: RHEL 7.9
PHP version:      Irrelevant
Package:          ODBC related
Bug Type:         Bug
Bug description:ODBC doesn't account for SQL_NO_TOTAL indicator, causing segmentation fault

Description:
------------
The ODBC extension (ext/odbc/php_odbc.c) causes a segmentation fault
when SQL_NO_TOTAL indicator is returned to a bound column from a call to
SQLFetch and similar functions.

There are two major issues:

1. There is an assumption that the number of bytes returned from a call
to SQLColAttribute with a type of SQL_DESC_OCTET_LENGTH will return the
number of bytes required to store the value. There are cases when data
is stored in an encoding which stores character data in a single byte,
which then needs to be converted to variable multi-byte when SQLFetch is
actually called (eg. EBCDIC 278 to UTF8 conversion). This might be a
broken driver implementation on our part, but the ODBC docs are rather
thin and at times seem contradictory on this point.

This will cause a buffer to be allocated of size X, where up to X * 4
may be needed to store a string. There is a variable in the code
(charextraalloc) to allocate buffers of this size, but none of the
checks work for ODBC v 3.0+ drivers. When the buffer is too small, the
driver may return SQL_NO_TOTAL when in the StrLen_or_IndPtr, as it
didn't have enough space for the column, and might not know how many
bytes are left.

2. The bigger issue is that calls to SQLFetch can return SQL_NO_TOTAL to
the StrLen_or_IndPtr stored on SQLBindCol when the buffer bound isn't
large enough for the data, but the code isn't checking for this.
Instead, the code checks if the value of StrLen_or_IndPtr is
SQL_NULL_DATA and assigns a value to null. If it isn't SQL_NULL_DATA, it
assumes that it holds the length of the string, then calls functions
like ZVAL_STRINGL and RETURN_STRINGL with SQL_NO_TOTAL (which evaluates
to -4) as the length. Trying to create a string with length of -4 causes
a segmentation fault, which causes the program to crash.

As mentioned, the first issue might be a problem in driver
implementation, but the second definitely needs to be fixed.
SQL_NO_TOTAL is definitely a valid StrLen_or_IndPtr value, and there are
no checks for it in the code, causing a segfault.


-- 
Edit bug report at https://bugs.php.net/bug.php?id=80460&edit=1
-- 
Fix committed:                    https://bugs.php.net/fix.php?id=80460&r=fixed
Fixed in release:                 https://bugs.php.net/fix.php?id=80460&r=alreadyfixed
Need backtrace:                   https://bugs.php.net/fix.php?id=80460&r=needtrace
Need Reproduce Script:            https://bugs.php.net/fix.php?id=80460&r=needscript
Try newer version:                https://bugs.php.net/fix.php?id=80460&r=oldversion
Not developer issue:              https://bugs.php.net/fix.php?id=80460&r=support
Expected behavior:                https://bugs.php.net/fix.php?id=80460&r=notwrong
Not enough info:                  https://bugs.php.net/fix.php?id=80460&r=notenoughinfo
Submitted twice:                  https://bugs.php.net/fix.php?id=80460&r=submittedtwice
register_globals:                 https://bugs.php.net/fix.php?id=80460&r=globals
PHP version support discontinued: https://bugs.php.net/fix.php?id=80460&r=phptooold
Daylight Savings:                 https://bugs.php.net/fix.php?id=80460&r=dst
IIS Stability:                    https://bugs.php.net/fix.php?id=80460&r=isapi
Install GNU Sed:                  https://bugs.php.net/fix.php?id=80460&r=gnused
Floating point limitations:       https://bugs.php.net/fix.php?id=80460&r=float
No Zend Extensions:               https://bugs.php.net/fix.php?id=80460&r=nozend
MySQL Configuration Error:        https://bugs.php.net/fix.php?id=80460&r=mysqlcfg


Thread (19 messages)

« previous php.bugs (#230781) next »