php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67130 nextRowset causes memory corruption
Submitted: 2014-04-24 20:24 UTC Modified: 2016-09-21 19:22 UTC
Votes:10
Avg. Score:4.7 ± 0.6
Reproduced:9 of 9 (100.0%)
Same Version:1 (11.1%)
Same OS:5 (55.6%)
From: kaido at tradenet dot ee Assigned: adambaratz
Status: Closed Package: PDO DBlib
PHP Version: master-Git-2014-04-24 (Git) OS: linux
Private report: No CVE-ID:
 [2014-04-24 20:24 UTC] kaido at tradenet dot ee
Description:
------------
php:
PHP 5.4.29-dev (cli) (built: Apr 24 2014 16:49:28) (DEBUG)

configured with:
./configure --enable-debug --with-mssql --with-pdo-dblib --enable-mbstring

calling PDOStatement::nextRowset() corrupts memory.

Test script:
---------------
replace server/database names and login credentials.

freetds.conf has 'tds version = 8.0' as only item in 'global' section.

<?php

        $dsn = "dblib:host=xxxxx.xxxx.xxx;dbname=xxx";
        $pdo = new PDO($dsn, 'user', 'password');

        $stmt = $pdo->query('select 1');
	$stmt->fetch();
	$stmt->nextRowset();

?>





Actual result:
--------------
[Thu Apr 24 23:19:09 2014]  Script:  '/webroot/k2/ekl/b1.php'
---------------------------------------
/root/php/php-src/ext/pdo/pdo_stmt.c(2074) : Block 0x03058a48 status:
Beginning:      Freed (magic=0x00000000, expected=0x99954317)
    Start:      Overflown (magic=0x00000000 instead of 0x541E9F24)
                At least 4 bytes overflown
      End:      Overflown (magic=0x00000000 instead of 0x546AF508)
                At least 4 bytes overflown
---------------------------------------

Warning: PDOStatement::nextRowset(): SQLSTATE[HY000]: General error: PDO_DBLIB: dbresults() returned FAIL in /webroot/k2/ekl/b1.php on line 10
[Thu Apr 24 23:19:09 2014]  Script:  '/webroot/k2/ekl/b1.php'
/root/php/php-src/ext/pdo_dblib/pdo_dblib.c(113) :  Freeing 0x7F109142F9C0 (8 bytes), script=/webroot/k2/ekl/b1.php
[Thu Apr 24 23:19:09 2014]  Script:  '/webroot/k2/ekl/b1.php'
/root/php/php-src/ext/pdo_dblib/pdo_dblib.c(118) :  Freeing 0x7F1091431490 (73 bytes), script=/webroot/k2/ekl/b1.php
=== Total 2 memory leaks detected ===


Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-04-26 08:29 UTC] kaido at tradenet dot ee
the problem/bug is as follows:

(1) ext/pdo/pdo_stmt.c:pdo_stmt_do_next_rowset() frees column names with efree()

(2) column names are set in ext/pdo_dblib/dblib_stmt.c:pdo_dblib_stmt_describe() with direct call to dbcolname(). the returned name points to a fixed structure and as such does not need to be freed later.

(3) ext/pdo_dblib/dblib_stmt.c:pdo_dblib_stmt_cursor_closer() and ext/pdo_dblib/dblib_stmt.c:pdo_dblib_stmt_stmt_dtor() know the fact (2) and do not free column names

(4) it seems that pdo expects the column names to be allocated - other drivers (oci, mysql etc) do it this way.


so the proposed solution/fix would be:

(a) in ext/pdo_dblib/dblib_stmt.c:pdo_dblib_stmt_describe() estrdup() the column name as follows:

col->name = (char*)estrdup(dbcolname(H->link, colno+1));

b) add the code:

        struct pdo_column_data *cols = stmt->columns;
        int i;
        for (i = 0; i < stmt->column_count; i++) {
                efree(cols[i].name);
        }


into ext/pdo_dblib/dblib_stmt.c:pdo_dblib_stmt_cursor_closer() and ext/pdo_dblib/dblib_stmt.c:pdo_dblib_stmt_stmt_dtor() to free column names in those code paths.

Can someone with better knowledge of the code here take a look, confirm my observations, and commit the fix, please.
 [2014-10-21 03:57 UTC] ssufficool@php.net
Instead of strdup I would null the col name pointers to (hopefully) cause pdo core to skip the deallocate. I would hate to introduce an ever so slight performance penalty with a strdup if not *absolutely* needed.
 [2014-10-21 04:07 UTC] ssufficool@php.net
-Assigned To: +Assigned To: ssufficool
 [2014-10-23 03:39 UTC] ssufficool@php.net
-Status: Assigned +Status: Feedback
 [2014-10-23 03:39 UTC] ssufficool@php.net
Please try using this snapshot:

  http://snaps.php.net/php-trunk-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/

Fixed along with Bug #64511
 [2014-12-30 10:42 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.
 [2015-07-06 19:59 UTC] John_Schlick at hotmail dot com
I have experienced this problem on PHP 5.5.9-1ubuntu4.5 using the PDO

A stored procedure results in a variable number of rowsets, (in this case, 3), on the 3rd call to nextrowset it returns true, so when I then trustingly do:
     $result = $stmt->fetch(\PDO::FETCH_OBJ);
it results in:
     SQLSTATE[HY000]: General error
 [2015-10-18 09:53 UTC] miracle at rpz dot name
Fixed in #69757
 [2016-09-21 19:22 UTC] adambaratz@php.net
-Status: No Feedback +Status: Closed -Assigned To: ssufficool +Assigned To: adambaratz
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Mon Feb 20 22:01:35 2017 UTC