[php-src] master: Merge branch 'PHP-8.5'

Ilia Alshanetsky <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Ilia Alshanetsky (iliaal)
Date: 2026-08-30T10:35:10-04:00

Commit: https://github.com/php/php-src/commit/0f36dcc2015651eb99ce7f8cc3bcd62acd39f2eb
Raw diff: https://github.com/php/php-src/commit/0f36dcc2015651eb99ce7f8cc3bcd62acd39f2eb.diff

Merge branch 'PHP-8.5'

* PHP-8.5:
  [mysqlnd] Fix OK packet message length buffer over-read

Changed paths:
  A  ext/mysqli/tests/mysqlnd_ok_packet_message_over_read.phpt
  M  ext/mysqli/tests/fake_server.inc
  M  ext/mysqlnd/mysqlnd_wireprotocol.c


Diff:

diff --git a/ext/mysqli/tests/fake_server.inc b/ext/mysqli/tests/fake_server.inc
index dad8bc52ddd1..4056b9fb78cf 100644
--- a/ext/mysqli/tests/fake_server.inc
+++ b/ext/mysqli/tests/fake_server.inc
@@ -721,6 +721,19 @@ function my_mysqli_test_auth_response_message_over_read(my_mysqli_fake_server_co
     $conn->read();
 }
 
+function my_mysqli_test_ok_packet_message_over_read(my_mysqli_fake_server_conn $conn): void
+{
+    $p = new my_mysqli_fake_packet();
+    $p->full = "08000001" . "00" . "00" . "00" . "0200" . "0000" . "fa";
+
+    $conn->send_server_greetings();
+    $conn->read_packets(1);
+    $conn->send_server_ok();
+    $conn->read_packets(1);
+    $conn->send($p->to_bytes(), "Malicious OK Packet [message length past the packet size]");
+    $conn->read();
+}
+
 function my_mysqli_test_stmt_response_row_over_read_string(my_mysqli_fake_server_conn $conn): void
 {
     $rh = $conn->packet_generator->server_stmt_execute_items_response();
diff --git a/ext/mysqli/tests/mysqlnd_ok_packet_message_over_read.phpt b/ext/mysqli/tests/mysqlnd_ok_packet_message_over_read.phpt
new file mode 100644
index 000000000000..8364251e8df4
--- /dev/null
+++ b/ext/mysqli/tests/mysqlnd_ok_packet_message_over_read.phpt
@@ -0,0 +1,40 @@
+--TEST--
+mysqlnd OK packet message length buffer over-read
+--EXTENSIONS--
+mysqli
+--FILE--
+<?php
+require_once 'fake_server.inc';
+
+$servername = "127.0.0.1";
+$username = "root";
+$password = "";
+
+$process = run_fake_server_in_background('ok_packet_message_over_read');
+$process->wait();
+
+try {
+    $conn = new mysqli( $servername, $username, $password, "", $process->getPort());
+    var_dump($conn->select_db("test"));
+} catch (Exception $e) {
+    echo $e::class, ": ", $e->getMessage(), PHP_EOL;
+}
+
+$process->terminate();
+
+print "done!";
+?>
+--EXPECTF--
+[*] Server started on 127.0.0.1:%d
+[*] Connection established
+[*] Sending - Server Greeting: %s
+[*] Received: %s
+[*] Sending - Server OK: %s
+[*] Received: %s
+[*] Sending - Malicious OK Packet [message length past the packet size]: %s
+
+Warning: mysqli::select_db(): OK packet message length is past the packet size in %s on line %d
+
+Warning: mysqli::select_db(): Error while reading INIT_DB's response packet. PID=%d in %s on line %d
+mysqli_sql_exception: Malformed packet
+done!
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index b957240a4088..5827ddeb06d6 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -876,7 +876,12 @@ php_mysqlnd_ok_read(MYSQLND_CONN_DATA * conn, void * _packet)
 
 	/* There is a message */
 	if (packet->header.size > (size_t) (p - buf) && (net_len = php_mysqlnd_net_field_length(&p))) {
-		packet->message_len = MIN(net_len, buf_len - (p - begin));
+		if ((p - buf) > packet->header.size || packet->header.size - (p - buf) < net_len) {
+			DBG_ERR_FMT("OK packet message length is past the packet size");
+			php_error_docref(NULL, E_WARNING, "OK packet message length is past the packet size");
+			DBG_RETURN(FAIL);
+		}
+		packet->message_len = net_len;
 		packet->message = mnd_pestrndup((char *)p, packet->message_len, FALSE);
 	} else {
 		packet->message = NULL;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.