Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cmb69/44a36b067a66f3770b914a7fa88e5086 to your computer and use it in GitHub Desktop.
Save cmb69/44a36b067a66f3770b914a7fa88e5086 to your computer and use it in GitHub Desktop.
Fix for PHP bug #76450
From 24ececffb3cceb7de874d0f6dc9384b80df0bd36 Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
Date: Fri, 30 Apr 2021 14:10:50 +0200
Subject: [PATCH] Fix #76450: SIGSEGV in firebird_stmt_execute
We need to verify that the `result_size` is not larger than our buffer,
and also should make sure that the `len` which is passed to
`isc_vax_integer()` has a permissible value; otherwise we bail out.
---
ext/pdo_firebird/firebird_statement.c | 7 +++++++
ext/pdo_firebird/tests/bug_76450.data | Bin 0 -> 464 bytes
ext/pdo_firebird/tests/bug_76450.phpt | 29 ++++++++++++++++++++++++++
3 files changed, 36 insertions(+)
create mode 100644 ext/pdo_firebird/tests/bug_76450.data
create mode 100644 ext/pdo_firebird/tests/bug_76450.phpt
diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c
index 05dfe46848..7a948c9bd3 100644
--- a/ext/pdo_firebird/firebird_statement.c
+++ b/ext/pdo_firebird/firebird_statement.c
@@ -136,8 +136,14 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
}
if (result[0] == isc_info_sql_records) {
unsigned i = 3, result_size = isc_vax_integer(&result[1], 2);
+ if (result_size > sizeof(result)) {
+ goto error;
+ }
while (result[i] != isc_info_end && i < result_size) {
short len = (short) isc_vax_integer(&result[i + 1], 2);
+ if (len != 1 && len != 2 && len != 4) {
+ goto error;
+ }
if (result[i] != isc_info_req_select_count) {
affected_rows += isc_vax_integer(&result[i + 3], len);
}
@@ -161,6 +167,7 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
return 1;
} while (0);
+error:
RECORD_ERROR(stmt);
return 0;
diff --git a/ext/pdo_firebird/tests/bug_76450.data b/ext/pdo_firebird/tests/bug_76450.data
new file mode 100644
index 0000000000000000000000000000000000000000..51f949cc210d194c6c95d2d9f78e1437f5f6f076
GIT binary patch
literal 464
zcmZQzV2Jzwzk#2Dfq@Z-S%DY?xP4O76O$|B9ZO3xAR-Vl2Fk%D&xx!U$_AMW10Z>1
zK1dvy50YmB2_gY>c_b+Yc~KSy4xoTE3s@T~I}2Er1xkapqU%TIgH$8)(d}0h|No!=
q-+z!Y0f^DO5Q+~%F+nw>n*q{*3{d3%0|Bxmkc}dbCI{jYEe`-nDiu=z
literal 0
HcmV?d00001
diff --git a/ext/pdo_firebird/tests/bug_76450.phpt b/ext/pdo_firebird/tests/bug_76450.phpt
new file mode 100644
index 0000000000..8d14c41059
--- /dev/null
+++ b/ext/pdo_firebird/tests/bug_76450.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Bug #76450 (SIGSEGV in firebird_stmt_execute)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_firebird')) die("skip pdo_firebird extension not available");
+if (!extension_loaded('sockets')) die("skip sockets extension not available");
+?>
+--FILE--
+<?php
+require_once "payload_server.inc";
+
+$address = run_server(__DIR__ . "/bug_76450.data");
+
+// no need to change the credentials; we're running against a fake server
+$dsn = "firebird:dbname=inet://$address/test";
+$username = 'SYSDBA';
+$password = 'masterkey';
+
+$dbh = new PDO($dsn, $username, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
+$sql = "EXECUTE PROCEDURE test_proc 123";
+$query = $dbh->prepare($sql);
+try {
+ $query->execute();
+} catch (Exception $ex) {
+ echo "{$ex->getMessage()}\n";
+}
+?>
+--EXPECT--
+SQLSTATE[HY000]: General error
--
2.31.1.windows.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment