Skip to content

Commit 08da7c7

Browse files
cmb69smalyshev
authored andcommitted
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.
1 parent bcbf8aa commit 08da7c7

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

ext/pdo_firebird/firebird_driver.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,17 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sq
206206
if (result[0] == isc_info_sql_records) {
207207
unsigned i = 3, result_size = isc_vax_integer(&result[1],2);
208208

209+
if (result_size > sizeof(result)) {
210+
ret = -1;
211+
goto free_statement;
212+
}
209213
while (result[i] != isc_info_end && i < result_size) {
210214
short len = (short)isc_vax_integer(&result[i+1],2);
215+
/* bail out on bad len */
216+
if (len != 1 && len != 2 && len != 4) {
217+
ret = -1;
218+
goto free_statement;
219+
}
211220
if (result[i] != isc_info_req_select_count) {
212221
ret += isc_vax_integer(&result[i+3],len);
213222
}

ext/pdo_firebird/tests/bug_76449.data

464 Bytes
Binary file not shown.

ext/pdo_firebird/tests/bug_76449.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Bug #76449 (SIGSEGV in firebird_handle_doer)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('pdo_firebird')) die("skip pdo_firebird extension not available");
6+
if (!extension_loaded('sockets')) die("skip sockets extension not available");
7+
?>
8+
--FILE--
9+
<?php
10+
require_once "payload_server.inc";
11+
12+
$address = run_server(__DIR__ . "/bug_76449.data");
13+
14+
// no need to change the credentials; we're running against a fake server
15+
$dsn = "firebird:dbname=inet://$address/test";
16+
$username = 'SYSDBA';
17+
$password = 'masterkey';
18+
19+
$dbh = new PDO($dsn, $username, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
20+
var_dump($dbh->exec("INSERT INTO test VALUES ('hihi2', 'xxxxx')"));
21+
?>
22+
--EXPECT--
23+
bool(false)

0 commit comments

Comments
 (0)