Skip to content

Commit 922ea34

Browse files
cmb69derickr
authored andcommitted
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.
1 parent 1d4c311 commit 922ea34

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

ext/pdo_firebird/firebird_statement.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,14 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
136136
}
137137
if (result[0] == isc_info_sql_records) {
138138
unsigned i = 3, result_size = isc_vax_integer(&result[1], 2);
139+
if (result_size > sizeof(result)) {
140+
goto error;
141+
}
139142
while (result[i] != isc_info_end && i < result_size) {
140143
short len = (short) isc_vax_integer(&result[i + 1], 2);
144+
if (len != 1 && len != 2 && len != 4) {
145+
goto error;
146+
}
141147
if (result[i] != isc_info_req_select_count) {
142148
affected_rows += isc_vax_integer(&result[i + 3], len);
143149
}
@@ -161,6 +167,7 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
161167
return 1;
162168
} while (0);
163169

170+
error:
164171
RECORD_ERROR(stmt);
165172

166173
return 0;

ext/pdo_firebird/tests/bug_76450.data

464 Bytes
Binary file not shown.

ext/pdo_firebird/tests/bug_76450.phpt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Bug #76450 (SIGSEGV in firebird_stmt_execute)
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_76450.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+
$sql = "EXECUTE PROCEDURE test_proc 123";
21+
$query = $dbh->prepare($sql);
22+
try {
23+
$query->execute();
24+
} catch (Exception $ex) {
25+
echo "{$ex->getMessage()}\n";
26+
}
27+
?>
28+
--EXPECT--
29+
SQLSTATE[HY000]: General error

0 commit comments

Comments
 (0)