php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79277 pdo_odbc accessing SAP 16.0 ASE Fatal error: Allowed memory size ...
Submitted: 2020-02-15 15:43 UTC Modified: 2021-09-02 10:30 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: khleung at isfactory dot com Assigned:
Status: Open Package: PDO ODBC
PHP Version: 7.4.2 OS: CentOS 7
Private report: No CVE-ID: None
 [2020-02-15 15:43 UTC] khleung at isfactory dot com
Description:
------------
Having installed

php 7.4.2 on CentOS 7 1804 64-bit (3.10.0-1062.12.1.el7.x86_64) on a VMware host : 
2 GB ram, 250G HardDisk and 1 CPU Core. 
PHP and necessary modules are installed via yum install php and also by compiling using source from php-7.4.2.tar.gz

With SAP SDK for ASE binary file SDKASE160003P_7-21012007.TGZ installed

A testing script was prepared to check the connecting

It works fine to query a simple varchar(3) with 
"SELECT name FROM sysusers ORDER BY uid ASC"  
but it crashed : 
SELECT name, environ FROM sysusers ORDER BY uid ASC
or even 
SELECT top 1 name, environ FROM sysusers ORDER BY uid ASC


with following message:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4294967320 bytes) in /home/sybase/sybconnect1.php on line 16

sysusers table layout as follow
 Column_name Type     Length Prec Scale Nulls  
 ----------- -------- ------ ---- ----- -----  
 suid        int           4 NULL  NULL     0  
 uid         int           4 NULL  NULL     0  
 gid         int           4 NULL  NULL     0  
 name        char         30 NULL  NULL     0  
 environ     varchar     255 NULL  NULL     1  
 user_status smallint      2 NULL  NULL     0  


via UnixODBC Client tool : isql
/bin/isql SB007H sa [sapassword]

all of the above query works perfectly without any error


Test script:
---------------
[sybase@nagioshost lib]$ vi sybconnect.php
<?php

//PDO Driver Connect to Sybase
try {
    //$pdo = new PDO("odbc:Driver={Adaptive Server Enterprise};NA=lx007hsyb,5000;Uid=sa;Pwd=[sapassword];");
    $pdo = new PDO("odbc:SB007H", "sa", "[sapassword]");

    $pdo_status = "dsn: odbc:SB007H Connected to ASE 16\n";
    echo $pdo_status;

    $getUsers = $pdo->prepare('SELECT name FROM sysusers ORDER BY uid ASC');

    while ($row = $stmt->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT)) {
      $data = $row[0] . "\t" . $row[1] . "\t" . $row[2] . "\n";
      print $data;
    }
    $stmt = null;

	$getUsers->execute();
	$users = $getUsers->fetchAll();
	if ($users) {
	    foreach ($users as $user) {
	        echo  $user['name']."\n";
	    }
	} else {
	    trigger_error('No users.');
	}

} catch(PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}
:wq



Expected result:
----------------
sysusers contains only 20 rows and so it was expected
All query result set can shown   

Actual result:
--------------
pdo_odnc FetchAll queries with column of varchar(255) crashed
with following message:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4294967320 bytes) in /home/sybase/sybconnect1.php on line 16

Patches

init-displaysize (last revision 2020-02-23 12:04 UTC by cmb@php.net)
odbc_tracelog_revised (last revision 2020-02-16 06:19 UTC by khleung at isfactory dot com)
odbc_tracelog (last revision 2020-02-16 06:08 UTC by khleung at isfactory dot com)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-02-15 17:11 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2020-02-15 17:11 UTC] cmb@php.net
Could you please provide an ODBC trace?  Make sure that it
contains no sensitive info before you post it.
 [2020-02-16 06:08 UTC] khleung at isfactory dot com
The following patch has been added/updated:

Patch Name: odbc_tracelog
Revision:   1581833287
URL:        https://bugs.php.net/patch-display.php?bug=79277&patch=odbc_tracelog&revision=1581833287
 [2020-02-16 06:19 UTC] khleung at isfactory dot com
The following patch has been added/updated:

Patch Name: odbc_tracelog_revised
Revision:   1581833940
URL:        https://bugs.php.net/patch-display.php?bug=79277&patch=odbc_tracelog_revised&revision=1581833940
 [2020-02-23 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2020-02-23 04:33 UTC] khleung at isfactory dot com
-Status: No Feedback +Status: Closed
 [2020-02-23 04:33 UTC] khleung at isfactory dot com
Problem still exits waiting for further recommendations
 [2020-02-23 07:01 UTC] requinix@php.net
-Status: Closed +Status: Re-Opened
 [2020-02-23 12:04 UTC] cmb@php.net
The following patch has been added/updated:

Patch Name: init-displaysize
Revision:   1582459492
URL:        https://bugs.php.net/patch-display.php?bug=79277&patch=init-displaysize&revision=1582459492
 [2020-02-23 12:05 UTC] cmb@php.net
Thanks for the ODBC trace, and sorry for the late reply!

It seems to me that we are not properly handling the retrieval of
the display size; the MS documentation of SQLColAttribute()[1]
states:

| Please note that some drivers may only write the lower 32-bit or
| 16-bit of a buffer and leave the higher-order bit unchanged.
| Therefore, applications should initialize the value to 0 before
| calling this function.

So can you please try the attached init-displaysize patch?

[1] <https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolattribute-function>
 [2020-02-23 12:05 UTC] cmb@php.net
-Status: Re-Opened +Status: Feedback
 [2020-03-08 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2020-03-08 07:48 UTC] khleung at isfactory dot com
[root@localhost ext]# cd /usr/local/src/php-7.4.2/ext/pdo_odbc/
[root@localhost pdo_odbc]# ls
config.m4   CREDITS        odbc_driver.lo  odbc_stmt.c   odbc_stmt.o  pdo_odbc.lo  php_pdo_odbc.h      tests
config.w32  odbc_driver.c  odbc_driver.o   odbc_stmt.lo  pdo_odbc.c   pdo_odbc.o   php_pdo_odbc_int.h
[root@localhost pdo_odbc]# vi odbc_stmt.c 

static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno)
{
        pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
        struct pdo_column_data *col = &stmt->columns[colno];
        RETCODE rc;
        SWORD   colnamelen;
        SQLULEN colsize;
        SQLLEN displaysize = 0;

...
:wq


[root@localhost pdo_odbc]# cd /usr/local/src/php-7.4.2/
[root@localhost php-7.4.2]# make
/bin/sh /usr/local/src/php-7.4.2/libtool --silent --preserve-dup-deps --mode=install cp ext/opcache/opcache.la /usr/local/src/php-7.4.2/modules
/bin/sh /usr/local/src/php-7.4.2/libtool --silent --preserve-dup-deps --mode=compile cc -I/usr/local/src/php-7.4.2/ext  -I/usr/include -DPDO_ODBC_TYPE=\"unixODBC\" -Iext/pdo_odbc/ -I/usr/local/src/php-7.4.2/ext/pdo_odbc/ -DPHP_ATOM_INC -I/usr/local/src/php-7.4.2/include -I/usr/local/src/php-7.4.2/main -I/usr/local/src/php-7.4.2 -I/usr/local/src/php-7.4.2/ext/date/lib -I/usr/include/libxml2 -I/usr/local/src/php-7.4.2/TSRM -I/usr/local/src/php-7.4.2/Zend    -I/usr/include -g -O2 -fvisibility=hidden -Wall -Wno-strict-aliasing -DZEND_SIGNALS   -c /usr/local/src/php-7.4.2/ext/pdo_odbc/odbc_stmt.c -o ext/pdo_odbc/odbc_stmt.lo 
/usr/local/src/php-7.4.2/ext/pdo_odbc/odbc_stmt.c: In function ‘odbc_stmt_describe’:
/usr/local/src/php-7.4.2/ext/pdo_odbc/odbc_stmt.c:573:4: warning: pointer targets in passing argument 3 of ‘SQLDescribeCol’ differ in signedness [-Wpointer-sign]
    &S->cols[colno].coltype, &colsize, NULL, NULL);
    ^
In file included from /usr/include/sqlext.h:43:0,
                 from /usr/include/sqlucode.h:784,
                 from /usr/local/src/php-7.4.2/ext/pdo_odbc/php_pdo_odbc_int.h:53,
                 from /usr/local/src/php-7.4.2/ext/pdo_odbc/odbc_stmt.c:29:
/usr/include/sql.h:644:24: note: expected ‘SQLCHAR *’ but argument is of type ‘char *’
     SQLRETURN  SQL_API SQLDescribeCol(SQLHSTMT StatementHandle,
                        ^
/usr/local/src/php-7.4.2/ext/pdo_odbc/odbc_stmt.c: In function ‘odbc_stmt_set_param’:
/usr/local/src/php-7.4.2/ext/pdo_odbc/odbc_stmt.c:781:4: warning: pointer targets in passing argument 2 of ‘SQLSetCursorName’ differ in signedness [-Wpointer-sign]
    rc = SQLSetCursorName(S->stmt, Z_STRVAL_P(val), Z_STRLEN_P(val));
    ^
In file included from /usr/include/sqlext.h:43:0,
....

Build complete.
Don't forget to run 'make test'.

[root@localhost php-7.4.2]# make install
Installing shared extensions:     /usr/lib/php/extensions/no-debug-non-zts-20190902/
Installing PHP CLI binary:        /usr/bin/
Installing PHP CLI man page:      /usr/php/man/man1/
Installing phpdbg binary:         /usr/bin/
Installing phpdbg man page:       /usr/php/man/man1/
Installing PHP CGI binary:        /usr/bin/
Installing PHP CGI man page:      /usr/php/man/man1/
Installing build environment:     /usr/lib/php/build/
Installing header files:          /usr/include/php/
Installing helper programs:       /usr/bin/
  program: phpize
  program: php-config
Installing man pages:             /usr/php/man/man1/
  page: phpize.1
  page: php-config.1
/usr/local/src/php-7.4.2/build/shtool install -c ext/phar/phar.phar /usr/bin
ln -s -f phar.phar /usr/bin/phar
Installing PDO headers:           /usr/include/php/ext/pdo/

[root@localhost php-7.4.2]# exit
[sybase@localhost ~]$ cd ~
[sybase@localhost ~]$ php sybconnect.php 
dsn: odbc:SB007H Connected to ASE 16

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4294967320 bytes) in /home/sybase/sybconnect.php on line 14
[sybase@localhost ~]$ which php
/usr/bin/php
[sybase@localhost ~]$ ls -l /usr/bin/php 
-rwxr-xr-x. 1 root root 32209632 Mar  8 23:34 /usr/bin/php
 [2020-03-08 09:11 UTC] requinix@php.net
-Status: No Feedback +Status: Re-Opened
 [2020-03-08 17:24 UTC] cmb@php.net
Thanks for checking!  Unfortunately, it's hard to guess what's
going on without being able to reproduce, and also because the
ODBC trace lacks some relevant information about out parameters
(although it looks generally fine).

I can imagine that the displaysize returned by SQLColAttribute()
is negative, but even in that case I cannot track down where that
excessive allocation would happen.  Still, it might help to try
with the following patch, which should print the retrieved
displaysizes to stderr:

 ext/pdo_odbc/odbc_stmt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c
index 18abc475b9..0d3cb45352 100644
--- a/ext/pdo_odbc/odbc_stmt.c
+++ b/ext/pdo_odbc/odbc_stmt.c
@@ -608,6 +608,7 @@ static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno)
 			return 0;
 		}
 	}
+	fprintf(stderr, "displaysize == %d\n", displaysize);
 	colsize = displaysize;
 
 	col->maxlen = S->cols[colno].datalen = colsize;
 [2020-03-08 17:25 UTC] cmb@php.net
-Status: Re-Opened +Status: Feedback
 [2020-03-22 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2020-03-22 12:23 UTC] hleung at isfactory dot com
[sybase@localhost ~]$ php sybconnect.php 
dsn: odbc:SB007H Connected to ASE 16
displaysize == 255
displaysize == 11
displaysize == 11
displaysize == 2
displaysize == 6
displaysize == 6
displaysize == 6
displaysize == 6
displaysize == 11
displaysize == 23
displaysize == 23
displaysize == 11
displaysize == 11
displaysize == 11
displaysize == 11
displaysize == 11
displaysize == 6
displaysize == 11
displaysize == 6
displaysize == 24
displaysize == 30
displaysize == 39
displaysize == 6
displaysize == 16
displaysize == 6
displaysize == 3
displaysize == 3
displaysize == 11
displaysize == 11

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4294967320 bytes) in /home/sybase/sybconnect.php on line 14
[sybase@localhost ~]$
 [2020-03-22 12:25 UTC] khleung at isfactory dot com
[sybase@localhost ~]$ php sybconnect.php 
dsn: odbc:SB007H Connected to ASE 16
displaysize == 255
displaysize == 11
displaysize == 11
displaysize == 2
displaysize == 6
displaysize == 6
displaysize == 6
displaysize == 6
displaysize == 11
displaysize == 23
displaysize == 23
displaysize == 11
displaysize == 11
displaysize == 11
displaysize == 11
displaysize == 11
displaysize == 6
displaysize == 11
displaysize == 6
displaysize == 24
displaysize == 30
displaysize == 39
displaysize == 6
displaysize == 16
displaysize == 6
displaysize == 3
displaysize == 3
displaysize == 11
displaysize == 11

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4294967320 bytes) in /home/sybase/sybconnect.php on line 14
[sybase@localhost ~]$


Seems not what you guess
 [2020-03-22 12:31 UTC] cmb@php.net
-Status: No Feedback +Status: Open -Assigned To: cmb +Assigned To:
 [2020-03-22 12:31 UTC] cmb@php.net
Indeed, apparently there are no negative display sizes.  I'm at a
loss; that probably needs to be debugged with a Sybase DB.
 [2020-07-01 19:52 UTC] net_surfer at mail dot com
It appears that the issue can be reproduced 100% of the time if a nullable varchar column getting selected actually contains a null value.
 [2020-08-10 17:40 UTC] khleung at isfactory dot com
net_surfer is right!

Please advise any quick fix for that.
 [2020-09-29 14:12 UTC] cmb@php.net
> It appears that the issue can be reproduced 100% of the time if
> a nullable varchar column getting selected actually contains a
> null value.

I cannot reproduce this with either the ODBC Driver for SQL Server
or the MySQL ODBC 8.0 Unicode driver on Windows, so this is
apparently driver (manager) specific.

Anyhow, after having another look at this issue, I still have no
idea where this excessive memory allocation would occur.  I think
that addressing the unitialized displaysize issue, and also the
-Wpointer-sign warnings is appropriate, but unless that resolves
this issue, targeting the "master" branch seems to be more
reasonable.
 [2021-09-01 18:20 UTC] dbccjob at gmail dot com
Is your SAP odbc library symlinked to the SQLLEN8 library version ? The issue you are facing makes think of it.

make sure the library points to the sqllen8 one, unless you run on an old linux.
libsybdrvodb.so -> libsybdrvodb-sqllen8.so

see
http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc20155.1600/doc/html/san1361915533650.html
 [2021-09-02 10:11 UTC] khleung at isfactory dot com
Yes, the symbolic was built by SAP ASE SDK installation.
 
[sybase@rhase02 lib]$ ls -l
total 21352
-rwxr-xr-x. 1 sybase sybase 5185504 Nov  7  2018 libsapcrypto.so
-rwxr-xr-x. 1 sybase sybase 5413262 Nov  7  2018 libsapssfs.so
-rwxr-xr-x. 1 sybase sybase  499679 Nov  7  2018 libslcryptokernel.so
-rwxr-xr-x. 1 sybase sybase     166 Nov  7  2018 libslcryptokernel.so.sha256
-rwxr-xr-x. 1 sybase sybase 3644274 Nov  7  2018 libsybdrvodb-sqllen4.so
-rwxr-xr-x. 1 sybase sybase 3453367 Nov  7  2018 libsybdrvodb-sqllen4.so.fbo
-rwxr-xr-x. 1 sybase sybase 3654515 Nov  7  2018 libsybdrvodb-sqllen8.so
lrwxrwxrwx. 1 sybase sybase      25 Feb 25  2019 libsybdrvodb.000 -> ./libsybdrvodb-sqllen4.so
lrwxrwxrwx. 1 sybase sybase      25 Apr 18  2019 libsybdrvodb.so -> ./libsybdrvodb-sqllen4.so
drwxrwxr-x. 5 sybase sybase      55 Feb 25  2019 locales
[sybase@rhase02 lib]$
 [2021-09-02 10:30 UTC] khleung at isfactory dot com
Oh, Sorry, I overlooked your comments 

I will try to use SQLLEN8 lib and see if the issues fixed.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC