php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73800 Sporadic segfault in mysqlnd with MYSQLI_OPT_INT_AND_FLOAT_NATIVE enabled
Submitted: 2016-12-21 15:14 UTC Modified: 2017-01-08 17:17 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: php at vanviegen dot net Assigned: krakjoe (profile)
Status: Closed Package: MySQLi related
PHP Version: 7.0.14 OS:
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: php at vanviegen dot net
New email:
PHP Version: OS:

 

 [2016-12-21 15:14 UTC] php at vanviegen dot net
Description:
------------
The segfault happens sporadically, usually when reading large amounts of data. The backtrace is instructive:

#0  php_mysqlnd_rowp_read_text_protocol_aux (row_buffer=<optimized out>, 
    fields=<optimized out>, field_count=<optimized out>, fields_metadata=0x7fa0dd9c5e20, 
    as_int_or_float=1 '\001', stats=0x7fa0dd95c460)
    at /usr/src/builddir/ext/mysqlnd/mysqlnd_wireprotocol.c:1674
#1  0x00007fa0d97a6239 in php_mysqlnd_result_buffered_zval_fetch_row_pub (
    result=<optimized out>, param=0x7fa0d9c146b0, flags=2, 
    fetched_anything=0x7ffebc5139a7 "")
    at /usr/src/builddir/ext/mysqlnd/mysqlnd_result.c:1078
#2  0x00007fa0d97a6705 in php_mysqlnd_res_fetch_into_pub (result=0x7fa0dd9c4500, flags=2, 
    return_value=0x7fa0d9c146b0, extension=MYSQLND_MYSQLI)
    at /usr/src/builddir/ext/mysqlnd/mysqlnd_result.c:1727
#3  0x00007fa0cfd044e7 in php_mysqli_fetch_into_hash (execute_data=0x7ffebc5138e0, 
    return_value=0x7fa0d9c146b0, override_flags=0, into_object=0)
    at /usr/src/builddir/ext/mysqli/mysqli.c:1275
#4  0x00007fa0dc0b7726 in ZEND_DO_FCALL_SPEC_HANDLER ()
    at /usr/src/builddir/Zend/zend_vm_execute.h:842
[...]

Which resolves to the second line of this code fragment of ext/mysqlnd/mysqlnd_wireprotocol.c: 

            if (as_int_or_float && perm_bind.php_type == IS_LONG) {
                zend_uchar save = *(p + len);
                /* We have to make it ASCIIZ temporarily */
                *(p + len) = '\0';

So when a row ends with a long (or a float), this writes past the end of the row_buffer. As the old value is restored later on in this function, this is usually not a problem. Unless of course it happens to access unmapped address space.

Test script:
---------------
This bug seems rather impossible to reproduce deterministically, sorry!


Patches

mysqlnd-segfault-atoi.diff (last revision 2016-12-21 15:55 UTC by php at vanviegen dot net)

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-01-08 17:17 UTC] krakjoe@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: krakjoe
 [2017-01-08 17:17 UTC] krakjoe@php.net
The fix for this bug has been committed.

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/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 13:01:29 2024 UTC