php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52546 pdo_dblib segmentation fault when iterating MONEY values
Submitted: 2010-08-05 22:04 UTC Modified: 2010-08-24 18:59 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:2 (100.0%)
From: rgagnon24 at gmail dot com Assigned: aharvey (profile)
Status: Closed Package: PDO related
PHP Version: 5.2.14 OS: CentOS 5.5
Private report: No CVE-ID: None
 [2010-08-05 22:04 UTC] rgagnon24 at gmail dot com
Description:
------------
Fix for bug 51213 released into 5.2.14 and 5.3.3 causes segmentation fault when an SQL query attempts to read MSSQL MONEY type columns, or aggregates of those column types.

Problem appears to be invalid val->data pointer passed to spprintf() call at line 174 of dblib_stmt.c

Oddly, the patch attached to bug 51213 works properly, but is not the same as what was comitted to the code base.

In the patch attached to 51213, val->data is properly emalloc'd some memory before any sprintf()-type of operation is performed.

Test script:
---------------
// On a table containing a MONEY (field named "amount");

$sql = "SELECT SUM(amount) FROM table";
$rs = $pdo->query($sql, PDO::FETCH_OBJ);
foreach($rs as $row) {
   var_dump($row);
}

Expected result:
----------------
Expected to see rows dumped from table.

Actual result:
--------------
Segmentation fault.

Patches

fix_pdo_dblib_MONEY_seg_fault_5.2.14 (last revision 2010-08-06 16:17 UTC by rgagnon24 at gmail dot com)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-08-06 01:32 UTC] felipe@php.net
Automatic comment from SVN on behalf of felipe
Revision: http://svn.php.net/viewvc/?view=revision&revision=301916
Log: - Fixed bug #52546 (pdo_dblib segmentation fault when iterating MONEY values)
 [2010-08-06 01:32 UTC] felipe@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: felipe
 [2010-08-06 01:32 UTC] felipe@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Thanks.
 [2010-08-06 17:42 UTC] rgagnon24 at gmail dot com
With patch committed to SVN (r301916), segmentation fault still occurs.

The issue is the val->data pointer is null at the time of spprintf() being called.  Using "8" in place of "val->len" or sizeof(DBFLT8) in the dbconvert() call does not help at all.
 [2010-08-06 18:18 UTC] rgagnon24 at gmail dot com
Patch uploaded as diff of actual SVN checkout this time.

Patch made from PHP_5_2 branch, but appears to be the same for PHP_5_3
 [2010-08-10 15:29 UTC] preben at ghost dot dk
Here's a fix.

Test code
---------
<?php
$dbh = new PDO('dblib:dbname=DB;host=HOST', 'USER', 'PASS');
$sth = $dbh->query  ('create table #tmp(col money)');
$sth = $dbh->query  ('insert into #tmp(col) values(123.25)');
$sth = $dbh->query  ('insert into #tmp(col) values(-123.25)');
$sth = $dbh->prepare('SELECT col FROM #tmp');
$sth->execute();
$r = $sth->fetchAll(2);
print_r($r);
---------

Output
---------
Array
(
    [0] => Array
        (
            [col] => 123.2500
        )

    [1] => Array
        (
            [col] => -123.2500
        )

)
---------

Diff
---------
--- php-5.3.3/ext/pdo_dblib/dblib_stmt.c        2010-03-08 13:39:44.000000000 +0100
+++ ../php-5.3.3/ext/pdo_dblib/dblib_stmt.c     2010-08-10 15:18:48.000000000 +0200
@@ -170,8 +170,10 @@
                                        case SQLMONEY4:
                                        case SQLMONEYN: {
                                                DBFLT8 money_value;
+                                               val->len = (2 * dbdatlen(H->link, i + 1)) + 32;
+                                               val->data = emalloc(val->len);
                                                dbconvert(NULL, S->cols[i].coltype, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLFLT8, (LPBYTE)&money_value, val->len);
-                                               val->len = spprintf(val->data, 0, "%.4f", money_value);
+                                               val->len = sprintf(val->data, "%.4f", money_value);
                                                }
                                                break;
                                        default:
---------
 [2010-08-13 18:25 UTC] aharvey@php.net
-Status: Closed +Status: Re-Opened
 [2010-08-13 18:25 UTC] aharvey@php.net
Reopening, given it's apparently still segfaulting. Felipe, can you cast an eye over the new patch, please?
 [2010-08-14 00:12 UTC] felipe@php.net
Automatic comment from SVN on behalf of felipe
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=302196
Log: - Fixed the fix for bug #52546
 [2010-08-14 00:14 UTC] felipe@php.net
-Status: Re-Opened +Status: Closed
 [2010-08-14 00:14 UTC] felipe@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

rgagnon24 and preben: the spprintf() function already allocates the memory, this is not the problem... The problem is that the function expect char** and I was passing char*. It must be fixed now.

Thanks for the testing.
 [2010-08-14 00:16 UTC] felipe@php.net
Just to inform, the fix for this bug was committed just for 5.3 branch. The trunk branch has a bit different code, due some others bugs fixes trunk-only. And 5.2 branch is just accepting security bug fixes.
 [2010-08-19 20:59 UTC] rgagnon24 at gmail dot com
As an FYI.  I've been able to confirm the r302196 commit does resolve the issue in 5.3.

I know 5.2 is closed for fixes, but to leave a note for anyone that wishes to manually patch their copy, this does fix it for the released 5.2.14 as well.

The only change I would suggest is maybe using sizeof(DBFLT8) in place of the hard-coded "8" integer in the call to dbconvert()
 [2010-08-24 16:03 UTC] aharvey@php.net
-Status: Closed +Status: Re-Opened -Assigned To: felipe +Assigned To: aharvey
 [2010-08-24 16:03 UTC] aharvey@php.net
Ilia's approved this for 5.2 as well. I'll merge the fix in later tonight, hopefully.
 [2010-08-24 18:58 UTC] aharvey@php.net
Automatic comment from SVN on behalf of aharvey
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=302745
Log: MFB5.3: The fix (and the fix to the fix) for bug #52546 (pdo_dblib segmentation
fault when iterating MONEY values).
 [2010-08-24 18:59 UTC] aharvey@php.net
-Status: Re-Opened +Status: Closed
 [2010-08-24 18:59 UTC] aharvey@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Oct 15 09:01:26 2024 UTC