From 55f6895f4b4c677272fd4ee1113acdbd99c4b5ab Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 17 May 2022 12:59:23 +0200 Subject: [PATCH 1/3] Fix #81720: Uninitialized array in pg_query_params() leading to RCE We must not free parameters which we haven't initialized yet. We also fix the not directly related issue, that we checked for the wrong value being `NULL`, potentially causing a segfault. --- ext/pgsql/pgsql.c | 6 +++--- ext/pgsql/tests/bug81720.phpt | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 ext/pgsql/tests/bug81720.phpt diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index f52ff884d83..7dcd56cf144 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -1994,7 +1994,7 @@ PHP_FUNCTION(pg_query_params) if (Z_TYPE(tmp_val) != IS_STRING) { php_error_docref(NULL, E_WARNING,"Error converting parameter"); zval_ptr_dtor(&tmp_val); - _php_pgsql_free_params(params, num_params); + _php_pgsql_free_params(params, i); RETURN_FALSE; } params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val)); @@ -5175,8 +5175,8 @@ PHP_FUNCTION(pg_send_execute) params[i] = NULL; } else { zend_string *tmp_str = zval_try_get_string(tmp); - if (UNEXPECTED(!tmp)) { - _php_pgsql_free_params(params, num_params); + if (UNEXPECTED(!tmp_str)) { + _php_pgsql_free_params(params, i); return; } params[i] = estrndup(ZSTR_VAL(tmp_str), ZSTR_LEN(tmp_str)); diff --git a/ext/pgsql/tests/bug81720.phpt b/ext/pgsql/tests/bug81720.phpt new file mode 100644 index 00000000000..d79f1fcdd61 --- /dev/null +++ b/ext/pgsql/tests/bug81720.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #81720 (Uninitialized array in pg_query_params() leading to RCE) +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +try { + pg_send_prepare($conn, "my_query", 'SELECT $1, $2'); + pg_get_result($conn); + pg_send_execute($conn, "my_query", [1, new stdClass()]); +} catch (Throwable $ex) { + echo $ex->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +Object of class stdClass could not be converted to string +Object of class stdClass could not be converted to string From 58006537fc5f133ae8549efe5118cde418b3ace9 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 6 Jun 2022 00:56:51 -0600 Subject: [PATCH 2/3] Fix bug #81719: mysqlnd/pdo password buffer overflow --- ext/mysqlnd/mysqlnd_wireprotocol.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 87b2e7c3133..e4a298adaea 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -771,7 +771,8 @@ php_mysqlnd_change_auth_response_write(MYSQLND_CONN_DATA * conn, void * _packet) MYSQLND_VIO * vio = conn->vio; MYSQLND_STATS * stats = conn->stats; MYSQLND_CONNECTION_STATE * connection_state = &conn->state; - zend_uchar * const buffer = pfc->cmd_buffer.length >= packet->auth_data_len? pfc->cmd_buffer.buffer : mnd_emalloc(packet->auth_data_len); + size_t total_packet_size = packet->auth_data_len + MYSQLND_HEADER_SIZE; + zend_uchar * const buffer = pfc->cmd_buffer.length >= total_packet_size? pfc->cmd_buffer.buffer : mnd_emalloc(total_packet_size); zend_uchar * p = buffer + MYSQLND_HEADER_SIZE; /* start after the header */ DBG_ENTER("php_mysqlnd_change_auth_response_write"); From d1be9369adff1b1f0a5cdbc419a8188eafa0f04d Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 6 Jun 2022 01:00:38 -0600 Subject: [PATCH 3/3] Update NEWS --- NEWS | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index b4e26799750..6507aeb02bb 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,14 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 7.4.30 +09 Jun 2022, PHP 7.4.30 +- mysqlnd: + . Fixed bug #81719: mysqlnd/pdo password buffer overflow. (CVE-2022-31626) + (c dot fol at ambionics dot io) + +- pgsql + . Fixed bug #81720: Uninitialized array in pg_query_params(). + (CVE-2022-31625) (cmb) 14 Apr 2022, PHP 7.4.29