Bug #80713 [Ver]: SegFault when disabling ATTR_EMULATE_PREPARES and MySQL 8.0

From: Date: Tue, 16 Feb 2021 14:19:51 +0000
Subject: Bug #80713 [Ver]: SegFault when disabling ATTR_EMULATE_PREPARES and MySQL 8.0
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-232198@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80713&edit=1

 ID:                 80713
 Updated by:         nikic@php.net
 Reported by:        php at attrib dot org
 Summary:            SegFault when disabling ATTR_EMULATE_PREPARES and
                     MySQL 8.0
 Status:             Verified
 Type:               Bug
 Package:            PDO MySQL
 Operating System:   Debian Buster
 PHP Version:        7.4.15
 Block user comment: N
 Private report:     N

 New Comment:

Wanted to report this upstream, but apparently you need to fill out https://profile.oracle.com/myprofile/account/create-account.jspx
for that, which is a no-go for obvious reasons.

Here is the wireshark dump of the problematic server response:

Frame 16: 152 bytes on wire (1216 bits), 152 bytes captured (1216 bits) on interface lo, id 0
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00)
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 3306, Dst Port: 42692, Seq: 155, Ack: 188, Len: 86
MySQL Protocol
    Packet Length: 12
    Packet Number: 1
    Response Code: OK Packet (0x00)
    Statement ID: 1
    Number of fields: 1
    Number of parameter: 1
    Warnings: 0
MySQL Protocol
    Packet Length: 5
    Packet Number: 2
    Response Code: EOF Packet (0xfe)
    EOF marker: 254
    Warnings: 0
    Server Status: 0x0002
MySQL Protocol
    Packet Length: 48
    Packet Number: 3
    Catalog: def
    Database: test
    Table: test
    Original table: test
    Name: updated
    Original name: updated
    Charset number: binary COLLATE binary (63)
    Length: 10
    Type: FIELD_TYPE_DATE (10)
    Flags: 0x0080
    Decimals: 0
MySQL Protocol
    Packet Length: 5
    Packet Number: 4
    Response Code: EOF Packet (0xfe)
    EOF marker: 254
    Warnings: 0
    Server Status: 0x0002


Previous Comments:
------------------------------------------------------------------------
[2021-02-16 14:11:26] nikic@php.net

A bit reduced:

$pdo = new PDO($dsn, 'root', '', [ 
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
]);

//$pdo->exec('CREATE TABLE test(updated DATE)');

$stmt = $pdo->prepare("SELECT * FROM test ORDER BY :orderBy DESC");
$stmt->execute(['orderBy' => 'updated']);
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));

So, obviously the query is invalid (you're trying to prepare an identifier, not a value) and
should fail.

This looks like a bug on the MySQL server side, because the server responds with COM_STMT_PREPARE_OK
with num_columns=1 and num_params=1, but then directly follows with an EOF in the parameter
definition block. The following column definition block is correct.

------------------------------------------------------------------------
[2021-02-05 12:58:01] php at attrib dot org

Forgot to mention, it works if I use mysql:5.7. Only with mysql:8.0

------------------------------------------------------------------------
[2021-02-05 12:56:12] php at attrib dot org

Description:
------------
Disabling ATTR_EMULATE_PREPARES produces a segmentation fault when using MySQL 8.0.

See test script.

Test setup:

Running a docker container for mysql (
docker run --rm -it -e MYSQL_ROOT_PASSWORD="test" -e MYSQL_DATABASE="systemA"
mysql:8)

With a empty test table (at least id, updated field)

Running the script in a second container using php:7.4.15-cli or php:8.0.2-cli docker image for PHP
and running "docker-php-ext-install mysqli pdo_mysql".

Then call the script and the SegFault happens.

gbd output:

(gdb) run mysql.php
Starting program: /usr/local/bin/php mysql.php
warning: Error disabling address space randomization: Operation not permitted
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0000555a8da07eb8 in ?? ()
(gdb) bt
#0  0x0000555a8da07eb8 in ?? ()
#1  0x0000555a8da04429 in ?? ()
#2  0x0000555a8da0e4ff in ?? ()
#3  0x00007f0d5b3f91cc in mysql_handle_preparer ()
   from /usr/local/lib/php/extensions/no-debug-non-zts-20190902/pdo_mysql.so
#4  0x0000555a8d8f38b5 in ?? ()
#5  0x00007f0d5b6514a5 in xdebug_execute_internal (current_execute_data=0x7f0d5b413160, 
    return_value=0x7f0d5b4130d0) at /tmp/pear/temp/xdebug/src/base/base.c:921
#6  0x0000555a8daf853c in execute_ex ()
#7  0x00007f0d5b650ae1 in xdebug_execute_ex (execute_data=0x7f0d5b413020)
    at /tmp/pear/temp/xdebug/src/base/base.c:803
#8  0x0000555a8daf9073 in zend_execute ()
#9  0x0000555a8da731a3 in zend_execute_scripts ()
#10 0x0000555a8da12dd0 in php_execute_script ()
#11 0x0000555a8dafb156 in ?? ()
#12 0x0000555a8d7acb4b in ?? ()
#13 0x00007f0d5e4b909b in __libc_start_main (main=0x555a8d7ac700, argc=2, argv=0x7ffeedecde78, 
    init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7ffeedecde68)
    at ../csu/libc-start.c:308
#14 0x0000555a8d7ad28a in _start ()
(gdb) 


Test script:
---------------
<?php
$pdo = new PDO(sprintf('mysql:dbname=%s;host=%s;charset=utf8', 'systemA',
'172.17.0.4:3306'), 'root', 'test', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_TIMEOUT => 30,
    PDO::ATTR_EMULATE_PREPARES => false,
]);

$resultAssoc = $pdo->prepare("SELECT * FROM test WHERE :field >= :date ORDER BY :orderBy
DESC LIMIT :offset, :limit");
$resultAssoc->execute([
    'field' => 'updated',
    'date' => (new DateTime('2020-02-01'))->format('Y-m-d
H:i:s'),
    'orderBy' => 'id',
    'limit' => 1000,
    'offset' => 0,
]);
var_dump($resultAssoc->fetchAll(PDO::FETCH_ASSOC));


Expected result:
----------------
Empty array if nothing is in the DB.

Actual result:
--------------
Segmentation fault (core dumped)


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=80713&edit=1


Thread (6 messages)

« previous php.bugs (#232198) next »