From 08da7c73726f7b86b67d6f0ff87c73c585a7834a Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 30 Apr 2021 13:53:21 +0200 Subject: [PATCH] Fix #76449: SIGSEGV in firebird_handle_doer 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_driver.c | 10 ++++++++++ ext/pdo_firebird/tests/bug_76449.phpt | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 ext/pdo_firebird/tests/bug_76449.phpt diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index c27a9e2e..303e0f47 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -626,8 +626,18 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sq if (result[0] == isc_info_sql_records) { unsigned i = 3, result_size = isc_vax_integer(&result[1],2); + if (result_size > sizeof(result)) { + ret = -1; + goto free_statement; + } + while (result[i] != isc_info_end && i < result_size) { short len = (short)isc_vax_integer(&result[i+1],2); + /* bail out on bad len */ + if (len != 1 && len != 2 && len != 4) { + ret = -1; + goto free_statement; + } if (result[i] != isc_info_req_select_count) { ret += isc_vax_integer(&result[i+3],len); } diff --git a/ext/pdo_firebird/tests/bug_76449.phpt b/ext/pdo_firebird/tests/bug_76449.phpt new file mode 100644 index 00000000..48a09c1d --- /dev/null +++ b/ext/pdo_firebird/tests/bug_76449.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #76449 (SIGSEGV in firebird_handle_doer) +--SKIPIF-- + +--FILE-- + PDO::ERRMODE_EXCEPTION]); +var_dump($dbh->exec("INSERT INTO test VALUES ('hihi2', 'xxxxx')")); +?> +--EXPECT-- +bool(false) -- 2.27.0