Skip to content

Commit 5d9e540

Browse files
nielsdosremicollet
authored andcommitted
Fix GHSA-5hqh-c84r-qjcv: Integer overflow in the dblib quoter causing OOB writes
(cherry picked from commit d9baa9fed8c3ba692a36b388c0c7762e5102e2e0)
1 parent af3fb38 commit 5d9e540

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

ext/pdo_dblib/dblib_driver.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unqu
152152

153153
size_t i;
154154
char * q;
155+
size_t extralen = 0;
155156
*quotedlen = 0;
156157

157158
if (H->assume_national_character_set_strings) {
@@ -166,14 +167,19 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unqu
166167

167168
/* Detect quoted length, adding extra char for doubled single quotes */
168169
for (i = 0; i < unquotedlen; i++) {
169-
if (unquoted[i] == '\'') ++*quotedlen;
170+
if (unquoted[i] == '\'') ++extralen;
170171
++*quotedlen;
171172
}
172173

173174
*quotedlen += 2; /* +2 for opening, closing quotes */
174175
if (use_national_character_set) {
175176
++*quotedlen; /* N prefix */
176177
}
178+
if (UNEXPECTED(*quotedlen > ZSTR_MAX_LEN - extralen)) {
179+
return 0;
180+
}
181+
182+
*quotedlen += extralen;
177183
q = *quoted = emalloc(*quotedlen + 1); /* Add byte for terminal null */
178184
if (use_national_character_set) {
179185
*q++ = 'N';
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
GHSA-5hqh-c84r-qjcv (Integer overflow in the dblib quoter causing OOB writes)
3+
--EXTENSIONS--
4+
pdo_dblib
5+
--SKIPIF--
6+
<?php
7+
if (PHP_INT_SIZE != 4) die("skip for 32bit platforms only");
8+
if (PHP_OS_FAMILY === "Windows") die("skip not for Windows because the virtual address space for application is only 2GiB");
9+
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
10+
require __DIR__ . '/config.inc';
11+
getDbConnection();
12+
?>
13+
--INI--
14+
memory_limit=-1
15+
--FILE--
16+
<?php
17+
18+
require __DIR__ . '/config.inc';
19+
$db = getDbConnection();
20+
var_dump($db->quote(str_repeat("'", 2147483646)));
21+
22+
?>
23+
--EXPECT--
24+
bool(false)

0 commit comments

Comments
 (0)