From:             
Operating system: Solaris Sparc
PHP version:      5.3.2
Package:          MySQL related
Bug Type:         Bug
Bug description:Bus error due to wrong alignment in mysqlnd

Description:
------------
Using any of pdo-mysql, mysqli or mysql against mysqlnd results in a bus
error on Solaris Sparc. This is due to a wrong alignment assumption that
produces crashes because Sparc is strict about alignment.



The resulting core inspected via GDB shows:



Core was generated by `bin/php -c lib/php.ini mysql.php'.

Program terminated with signal 10, Bus error.

#0  0x0027d7f4 in php_mysqlnd_net_send_pub (conn=0x669928, buf=0xffbeee63
"", count=1)

    at /some/path/php53/ext/mysqlnd/mysqlnd_net.c:281

281                             STORE_HEADER_SIZE(safe_storage, p);



(gdb) bt full

#0  0x0027d7f4 in php_mysqlnd_net_send_pub (conn=0x669928, buf=0xffbeee63
"", count=1)

    at /some/path/php53/ext/mysqlnd/mysqlnd_net.c:281

        safe_buf = "\000\000\000"

        net = (MYSQLND_NET *) 0x669370

        old_chunk_size = 8192

        ret = 0

        packets_sent = 1

        left = 1

        p = (zend_uchar *) 0xffbeee63 ""

        compress_buf = (zend_uchar *) 0x0

        to_be_sent = 1

#1  0x0027552c in php_mysqlnd_cmd_write (_packet=0x6692b8, conn=0x669928)

    at /some/path/php53/ext/mysqlnd/mysqlnd_wireprotocol.c:683

        buffer = "\000\000\000\000\001"

        net = (MYSQLND_NET *) 0x669370

        written = <value optimized out>

#2  0x00272154 in php_mysqlnd_conn_simple_command_pub (conn=0x669928,
command=COM_QUIT, arg=<value optimized out>, arg_len=<value optimized out>,
ok_packet=PROT_LAST,

    silent=1 '\001', ignore_upsert_status=1 '\001') at
/some/path/php53/ext/mysqlnd/mysqlnd.c:380

        _p_s = (MYSQLND_STATS *) 0x7efa10

        ret = <value optimized out>

        cmd_packet = (MYSQLND_PACKET_COMMAND *) 0x6692b8

#3  0x0026f920 in mysqlnd_send_close (conn=0x669928) at
/some/path/php53/ext/mysqlnd/mysqlnd.c:1393

        ret = <value optimized out>

#4  0x00270560 in php_mysqlnd_conn_close_pub (conn=0x669928,
close_type=<value optimized out>)

    at /some/path/php53/ext/mysqlnd/mysqlnd.c:1461

        _p_s = (MYSQLND_STATS *) 0x7dafb8

        stat = STAT_CLOSE_EXPLICIT

        close_type_to_stat_map = {STAT_CLOSE_EXPLICIT, STAT_CLOSE_IMPLICIT,
STAT_CLOSE_DISCONNECT}

#5  0xfee47a70 in _close_mysql_link (rsrc=0x672150) at
/some/path/php53/ext/mysql/php_mysql.c:355

        link = (php_mysql_conn *) 0x669358

        handler = (void (*)(int)) 0x1

...



(gdb) print p

$1 = (zend_uchar *) 0xffbeee63 ""

(gdb) up

#1  0x0027552c in php_mysqlnd_cmd_write (_packet=0x6692b8, conn=0x669928)

    at /some/path/php53/ext/mysqlnd/mysqlnd_wireprotocol.c:683

683                     written = conn->net->m.send(conn, buffer, 1
TSRMLS_CC);

(gdb) print &buffer

$2 = (char (*)[5]) 0xffbeee63



Further Analysis shows:



- STORE_HEADER_SIZE() is a macro defined in the same file as:

    int4store((safe_storage), (*(uint32_t *)(buffer)))

  Note that "buffer" gets cast via (uint32_t *)



- buffer is not aligned on a 4 byte boundary, in fact it is an odd
address.

  In the above example it was allocated in line 680 of
mysqlnd_wireprotocol.c,

  without any alignment enforcement: "char buffer[MYSQLND_HEADER_SIZE +
1];"



- thus casting buffer to an (unsigned int *) crashes



Since both macros STORE_HEADER_SIZE and RESTORE_HEADER_SIZE seem to be used
in places, where there can be made no assumption about the alignment of the
buffer, the attached patch proposes to copy the header bytes as four
individual byte operations. Platform specific optimizations might be
applied, but at least the patch seems to be a robust solution. The patch
was done against trunk, same patch applies with offset to 5_3 branch.

Test script:
---------------
<h2>MySQL Test</h2>

<?php

  ini_set ('display_errors', true);



// Enter your database connection info here

  $db_server = 'myserv';

  $db_port = '3306';

  $db_name = 'mysql';

  $db_username = 'myuser';

  $db_password = 'mypass';



  echo 'Connecting ...<br>';

  $connection = mysql_connect("$db_server:$db_port", $db_username,
$db_password, $db_name);

  if (! $connection) {

    echo "<br><b>ERROR - Unable to connect to database server
'$db_server:$db_port': ". mysql_error() . '</b><br>';

    return FALSE;

  }

  echo 'Host Info: ' . mysql_get_host_info() . '<br>';

  echo 'Server Info: ' . mysql_get_server_info() . '<br>';

  echo 'Protocol Info: ' . mysql_get_proto_info() . '<br>';

  echo 'Client Info: ' . mysql_get_client_info() . '<br>';

  mysql_close($connection);

?>



Expected result:
----------------
<h2>MySQL Test</h2>

Connecting ...<br>Host Info: sorbus-07 via TCP/IP<br>Server Info:
5.0.27-standard<br>Protocol Info: 10<br>Client Info: mysqlnd 5.0.7-dev -
091210 - $Revision: 294543 $<br>

Actual result:
--------------
<h2>MySQL Test</h2>

Connecting ...<br>Host Info: sorbus-07 via TCP/IP<br>Server Info:
5.0.27-standard<br>Protocol Info: 10<br>Client Info: mysqlnd 5.0.7-dev -
091210 - $Revision: 294543 $<br>Bus Error (core dumped)





Note the trailing "Bus Error ..".

The result was produced by running PHP via CLI.



-- 
Edit bug report at http://bugs.php.net/bug.php?id=51583&edit=1
-- 
Try a snapshot (PHP 5.2):            
http://bugs.php.net/fix.php?id=51583&r=trysnapshot52
Try a snapshot (PHP 5.3):            
http://bugs.php.net/fix.php?id=51583&r=trysnapshot53
Try a snapshot (PHP 6.0):            
http://bugs.php.net/fix.php?id=51583&r=trysnapshot60
Fixed in SVN:                        
http://bugs.php.net/fix.php?id=51583&r=fixed
Fixed in SVN and need be documented: 
http://bugs.php.net/fix.php?id=51583&r=needdocs
Fixed in release:                    
http://bugs.php.net/fix.php?id=51583&r=alreadyfixed
Need backtrace:                      
http://bugs.php.net/fix.php?id=51583&r=needtrace
Need Reproduce Script:               
http://bugs.php.net/fix.php?id=51583&r=needscript
Try newer version:                   
http://bugs.php.net/fix.php?id=51583&r=oldversion
Not developer issue:                 
http://bugs.php.net/fix.php?id=51583&r=support
Expected behavior:                   
http://bugs.php.net/fix.php?id=51583&r=notwrong
Not enough info:                     
http://bugs.php.net/fix.php?id=51583&r=notenoughinfo
Submitted twice:                     
http://bugs.php.net/fix.php?id=51583&r=submittedtwice
register_globals:                    
http://bugs.php.net/fix.php?id=51583&r=globals
PHP 4 support discontinued:          http://bugs.php.net/fix.php?id=51583&r=php4
Daylight Savings:                    http://bugs.php.net/fix.php?id=51583&r=dst
IIS Stability:                       
http://bugs.php.net/fix.php?id=51583&r=isapi
Install GNU Sed:                     
http://bugs.php.net/fix.php?id=51583&r=gnused
Floating point limitations:          
http://bugs.php.net/fix.php?id=51583&r=float
No Zend Extensions:                  
http://bugs.php.net/fix.php?id=51583&r=nozend
MySQL Configuration Error:           
http://bugs.php.net/fix.php?id=51583&r=mysqlcfg

Reply via email to