Skip to content

Segfault: Pdo\Mysql::getWarningCount() dereferences the pool template with PDO::ATTR_POOL_ENABLED #201

Description

@EdmondDantes

Summary

With PDO::ATTR_POOL_ENABLED, Pdo\Mysql::getWarningCount() segfaults unconditionally. One line of userland PHP is enough.

In pool mode the userland PDO object's pdo_dbh_t is a template whose driver_data is always NULL — real connections live in pool slots. getWarningCount() reads driver_data off Z_PDO_DBH_P(ZEND_THIS) (always the template) and dereferences it.

ext/pdo_mysql/pdo_mysql.c:96-97:

H = dbh->driver_data;
RETURN_LONG(mysql_warning_count(H->server));   /* H == NULL in pool mode */

Reproducer

<?php
$pdo = new Pdo\Mysql(
    'mysql:host=localhost;unix_socket=/var/run/mysqld/mysqld.sock;dbname=test',
    'test', 'test',
    [PDO::ATTR_POOL_ENABLED => true, PDO::ATTR_POOL_MIN => 1, PDO::ATTR_POOL_MAX => 4]
);
echo "constructed pooled Pdo\\Mysql\n";
echo "getWarningCount() = ", $pdo->getWarningCount(), "\n";
constructed pooled Pdo\Mysql
getWarningCount() = Segmentation fault (core dumped)   # exit 139

Crashes even when a slot connection is live (i.e. right after a successful query), because the template is what gets dereferenced, not the slot.

Suggested fix

Route through pdo_pool_peek_conn(dbh) and return 0 when no slot connection is bound to the current context — same shape as the existing lastInsertId / errorInfo handling.

Related

ext/pdo_mysql/pdo_mysql.c:74 pdo_mysql_convert_zv_to_mysqlnd (the mysqlnd reverse-API entry point) reads driver_data the same way. Not executed, so unconfirmed, but it looks like the same defect.

Environment

PHP        8.6.0-dev (cli) (ZTS DEBUG TrueAsync ABI v0.24.0)
true_async 0.7.10
pdo_mysql  8.6.0-dev
OS         Linux 6.6.114.1-microsoft-standard-WSL2

Found while auditing the pool code path for #200; pre-existing, independent of that fix.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions