|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78680 mysqlnd's mysql_clear_password does not transmit null-terminated password
Submitted: 2019-10-17 18:47 UTC Modified: 2021-01-13 16:36 UTC
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: geoff dot montee at gmail dot com Assigned:
Status: Closed Package: MySQLi related
PHP Version: 7.3.10 OS: Alpine Linux v3.10
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: geoff dot montee at gmail dot com
New email:
PHP Version: OS:


 [2019-10-17 18:47 UTC] geoff dot montee at gmail dot com
The mysql_clear_password client authentication plugin is supposed to transmit a null-terminated password to the server. This is described in the following code comment:

"  @startuml
  Server->Client: 20 bytes of scramble to be ignored
  Client->Server: The clear text password. null terminated.

PHP's implementation of mysql_clear_password in the mysqlnd driver does not seem to transmit the terminating NULL character with the password. See here:

This can easily be reproduced.


Let's say that I have a server running MariaDB 10.4.8. We can configure PAM authentication by performing the following steps:

1.) Create a Unix user account and set a password for the user:

sudo useradd alice
sudo passwd alice

The examples below assume that the password is "uGBXHxID3dJRALw2".

2.) Create the PAM service configuration:

sudo tee /etc/pam.d/mariadb <<EOF
auth required audit
account required audit

3.) Install the pam plugin:

sudo mysql --execute="INSTALL SONAME 'auth_pam'"

4.) Create the relevant user:

sudo mysql --execute="CREATE USER 'alice'@'localhost' IDENTIFIED VIA pam USING 'mariadb'"

5.) Enable the pam_use_cleartext_plugin system variable:

$ sudo mysql -u root --execute="SHOW GLOBAL VARIABLES LIKE 'pam%'"
| Variable_name            | Value |
| pam_use_cleartext_plugin | ON    |
| pam_winbind_workaround   | OFF   |

At this point, PAM is configured.


Let's say that I set up PHP 7.3.10 on the same server as the database.

The connectivity can easily be tested by creating the following test script:

tee pamtest.php << EOF
\$link = mysqli_connect("", "alice", "uGBXHxID3dJRALw2", "test");
if (!\$link) {
    echo "Error: Unable to connect to MySQL." . PHP_EOL;
    echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
    echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
echo "Success: A proper connection to MySQL was made! The my_db database is great." . PHP_EOL;
echo "Host information: " . mysqli_get_host_info(\$link) . PHP_EOL;
php -f pamtest.php


So let's run the test script, and do some debugging.

1.) First, let's attach strace to the mysqld process:

sudo mkdir strace/
cd strace/
sudo strace -o strace.out -f -ff -p $(pidof mysqld)

2.) And then let's also run the PHP script while attaching strace to that process:

strace -o strace.out -f -ff php -f pamtest.php

Authentication will fail on MariaDB 10.4.8, since that MariaDB version currently treats the NULL terminating character as mandatory:

Warning: mysqli_connect(): (HY000/1045): Access denied for user 'alice'@'localhost' (using password: NO) in /var/www/html/pamtest.php on line 2
Error: Unable to connect to MySQL.
Debugging errno: 1045
Debugging error: Access denied for user 'alice'@'localhost' (using password: NO)

The strace output of the PHP script shows that the NULL terminating character is not set:

./strace.out.3393-recvfrom(3, "\26\0\0\2\376mysql_clear_password\0", 32768, MSG_DONTWAIT, NULL, NULL) = 26
./strace.out.3393:sendto(3, "\20\0\0\3uGBXHxID3dJRALw2", 20, MSG_DONTWAIT, NULL, 0) = 20

And the strace output of mysqld shows the same thing:

sendto(154, "\26\0\0\2\376mysql_clear_password\0", 26, MSG_DONTWAIT, NULL, 0) = 26
recvfrom(154, "\20\0\0\3", 4, MSG_DONTWAIT, NULL, NULL) = 4
recvfrom(154, "uGBXHxID3dJRALw2", 16, MSG_DONTWAIT, NULL, NULL) = 16

In contrast, here's the strace output of mysqld with a "working" client:

sendto(154, "\26\0\0\2\376mysql_clear_password\0", 26, MSG_DONTWAIT, NULL, 0) = 26
recvfrom(154, "\21\0\0\3", 4, MSG_DONTWAIT, NULL, NULL) = 4
recvfrom(154, "uGBXHxID3dJRALw2\0", 17, MSG_DONTWAIT, NULL, NULL) = 17


Add a Patch

Pull Requests

Pull requests:

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-10-17 19:34 UTC] geoff dot montee at gmail dot com
This problem was discovered due to the following two MariaDB bug reports:
 [2021-01-13 16:36 UTC]
Well, that looks indeed wrong in mysqldn.  Would you mind to
provide a pull request[1]?

[1] <>
 [2021-02-05 21:38 UTC] geoff dot montee at gmail dot com
The following pull request has been associated:

Patch Name: Fix #78680: mysqlnd pam plugin missing terminating null
On GitHub:
 [2021-02-15 10:33 UTC]
Automatic comment on behalf of
Log: Fix #78680: mysqlnd pam plugin missing terminating null
 [2021-02-15 10:33 UTC]
-Status: Open +Status: Closed
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Wed Mar 03 05:01:25 2021 UTC