Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Proposed patch for PHP bug #81720
From 86a488b11f8eb37ab98a0e13246cd4ce74e67bb3 Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
Date: Tue, 17 May 2022 12:59:23 +0200
Subject: [PATCH] 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 f52ff884d8..7dcd56cf14 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 0000000000..d79f1fcdd6
--- /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--
+<?php include("skipif.inc"); ?>
+--FILE--
+<?php
+include('config.inc');
+
+$conn = pg_connect($conn_str);
+
+try {
+ pg_query_params($conn, 'SELECT $1, $2', [1, new stdClass()]);
+} catch (Throwable $ex) {
+ echo $ex->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
--
2.36.1.windows.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment