From 884900f39ff9ac4ef014ed7488d4ae1c553ba21d Mon Sep 17 00:00:00 2001 From: lazerg Date: Tue, 13 Oct 2026 17:54:03 +0500 Subject: [PATCH 1/3] Fix GH-24293: Segfault on connect with empty password to MariaDB PAM --- NEWS | 4 ++++ ext/mysqlnd/mysqlnd_auth.c | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 4b34324de64b..6e0e77104ad7 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,10 @@ PHP NEWS - MBString: . Fixed bug GH-23958 (truncated encoding names resolving to full names). (Kamil Tekiela) +- MySQLnd: + . Fixed bug GH-24293 (Segfault on connect with an empty password to a + MariaDB PAM account). (lazerg) + - Opcache: . Fixed bug GH-20890 (Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT). (ndossche) diff --git a/ext/mysqlnd/mysqlnd_auth.c b/ext/mysqlnd/mysqlnd_auth.c index ea9755c982ed..69bf2abbe065 100644 --- a/ext/mysqlnd/mysqlnd_auth.c +++ b/ext/mysqlnd/mysqlnd_auth.c @@ -629,9 +629,7 @@ mysqlnd_pam_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self, zend_uchar * ret = NULL; /* copy pass*/ - if (passwd && passwd_len) { - ret = (zend_uchar*) zend_strndup(passwd, passwd_len); - } + ret = (zend_uchar*) zend_strndup(passwd, passwd_len); /* Trailing null required. bug#78680 https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_authentication_methods_clear_text_password.html From 5612ebacc05ded7e6ce813c4f16ab09399238600 Mon Sep 17 00:00:00 2001 From: lazerg Date: Tue, 13 Oct 2026 18:58:15 +0500 Subject: [PATCH 2/3] Add test for GH-24293 --- ext/mysqli/tests/fake_server.inc | 15 +++++++++++++++ ext/mysqli/tests/gh24293.phpt | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 ext/mysqli/tests/gh24293.phpt diff --git a/ext/mysqli/tests/fake_server.inc b/ext/mysqli/tests/fake_server.inc index 238c5db31daf..4658d6ab1dad 100644 --- a/ext/mysqli/tests/fake_server.inc +++ b/ext/mysqli/tests/fake_server.inc @@ -1185,6 +1185,21 @@ function my_mysqli_test_cached_sha2_switch_unterminated(my_mysqli_fake_server_co $conn->read(65536); } +function my_mysqli_test_auth_switch_clear_password(my_mysqli_fake_server_conn $conn): void +{ + $p = new my_mysqli_fake_packet(); + $p->packet_length = "160000"; + $p->packet_number = "02"; + $p->response_code = "fe"; + $p->auth_plugin_name = bin2hex('mysql_clear_password' . chr(0)); + + $conn->send_server_greetings(); + $conn->read(); + $conn->send($p->to_bytes(), "Auth Switch Request [mysql_clear_password]"); + $conn->read(); + $conn->send($conn->packet_generator->server_ok("04")->to_bytes(), "Server OK"); +} + function my_mysqli_test_chg_user_response_empty(my_mysqli_fake_server_conn $conn): void { $p = $conn->packet_generator->server_ok("01"); diff --git a/ext/mysqli/tests/gh24293.phpt b/ext/mysqli/tests/gh24293.phpt new file mode 100644 index 000000000000..3898640a22ee --- /dev/null +++ b/ext/mysqli/tests/gh24293.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-24293 (Segfault on connect with an empty password to a MariaDB PAM account) +--EXTENSIONS-- +mysqli +--FILE-- +wait(); + +$conn = new mysqli($servername, $username, $password, "", $process->getPort()); +$conn->close(); + +$process->terminate(true); + +print "done!"; +?> +--EXPECTF-- +[*] Server started on 127.0.0.1:%d +[*] Connection established +[*] Sending - Server Greeting: 580000000a352e352e352d31302e352e31382d4d6172696144420003000000473e3f6047257c6700fef7080200ff81150000000000000f0000006c6b55463f49335f686c6431006d7973716c5f6e61746976655f70617373776f7264 +[*] Received: 6900000185a21a00000000c0080000000000000000000000000000000000000000000000726f6f7400006d7973716c5f6e61746976655f70617373776f7264002c0c5f636c69656e745f6e616d65076d7973716c6e640c5f7365727665725f686f7374093132372e302e302e31 +[*] Sending - Auth Switch Request [mysql_clear_password]: 16000002fe6d7973716c5f636c6561725f70617373776f726400 +[*] Received: 0100000300 +[*] Sending - Server OK: 0700000400000002000000 +[*] Server finished +done! From 67287f8bf53c9c2a2f2b863f52134530d29fad87 Mon Sep 17 00:00:00 2001 From: lazerg Date: Tue, 13 Oct 2026 19:53:11 +0500 Subject: [PATCH 3/3] Send a scramble with the auth switch in the GH-24293 test --- ext/mysqli/tests/fake_server.inc | 4 +++- ext/mysqli/tests/gh24293.phpt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ext/mysqli/tests/fake_server.inc b/ext/mysqli/tests/fake_server.inc index 4658d6ab1dad..2a4d17f946e8 100644 --- a/ext/mysqli/tests/fake_server.inc +++ b/ext/mysqli/tests/fake_server.inc @@ -1188,10 +1188,12 @@ function my_mysqli_test_cached_sha2_switch_unterminated(my_mysqli_fake_server_co function my_mysqli_test_auth_switch_clear_password(my_mysqli_fake_server_conn $conn): void { $p = new my_mysqli_fake_packet(); - $p->packet_length = "160000"; + $p->packet_length = "2b0000"; $p->packet_number = "02"; $p->response_code = "fe"; $p->auth_plugin_name = bin2hex('mysql_clear_password' . chr(0)); + // servers always send a fresh scramble with the switch request + $p->auth_plugin_data = "473e3f6047257c676c6b55463f49335f686c643100"; $conn->send_server_greetings(); $conn->read(); diff --git a/ext/mysqli/tests/gh24293.phpt b/ext/mysqli/tests/gh24293.phpt index 3898640a22ee..01bee5126aa6 100644 --- a/ext/mysqli/tests/gh24293.phpt +++ b/ext/mysqli/tests/gh24293.phpt @@ -25,7 +25,7 @@ print "done!"; [*] Connection established [*] Sending - Server Greeting: 580000000a352e352e352d31302e352e31382d4d6172696144420003000000473e3f6047257c6700fef7080200ff81150000000000000f0000006c6b55463f49335f686c6431006d7973716c5f6e61746976655f70617373776f7264 [*] Received: 6900000185a21a00000000c0080000000000000000000000000000000000000000000000726f6f7400006d7973716c5f6e61746976655f70617373776f7264002c0c5f636c69656e745f6e616d65076d7973716c6e640c5f7365727665725f686f7374093132372e302e302e31 -[*] Sending - Auth Switch Request [mysql_clear_password]: 16000002fe6d7973716c5f636c6561725f70617373776f726400 +[*] Sending - Auth Switch Request [mysql_clear_password]: 2b000002fe6d7973716c5f636c6561725f70617373776f726400473e3f6047257c676c6b55463f49335f686c643100 [*] Received: 0100000300 [*] Sending - Server OK: 0700000400000002000000 [*] Server finished