Skip to content

Commit 00ad59f

Browse files
committed
Check for connect buffer overflow
1 parent e1a3253 commit 00ad59f

2 files changed

Lines changed: 38 additions & 22 deletions

File tree

interbase.c

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -995,46 +995,45 @@ int _php_ibase_attach_db(char **args, size_t *len, zend_long *largs, isc_db_hand
995995

996996
for (i = 0; i < sizeof(dpb_args); ++i) {
997997
if (dpb_args[i] && args[i] && len[i] && buf_len > 0) {
998-
dpb_len = slprintf(dpb, buf_len, "%c%c%s", dpb_args[i],(unsigned char)len[i],args[i]);
998+
dpb_len = snprintf(dpb, buf_len, "%c%c%s", dpb_args[i],(unsigned char)len[i],args[i]);
999999
dpb += dpb_len;
10001000
buf_len -= dpb_len;
10011001
}
10021002
}
10031003
if (largs[BUF] && buf_len > 0) {
1004-
dpb_len = slprintf(dpb, buf_len, "%c\2%c%c", isc_dpb_num_buffers,
1004+
dpb_len = snprintf(dpb, buf_len, "%c\2%c%c", isc_dpb_num_buffers,
10051005
(char)(largs[BUF] >> 8), (char)(largs[BUF] & 0xff));
10061006
dpb += dpb_len;
10071007
buf_len -= dpb_len;
10081008
}
10091009
if (largs[SYNC] && buf_len > 0) {
1010-
dpb_len = slprintf(dpb, buf_len, "%c\1%c", isc_dpb_force_write, largs[SYNC] == isc_spb_prp_wm_sync);
1010+
dpb_len = snprintf(dpb, buf_len, "%c\1%c", isc_dpb_force_write, largs[SYNC] == isc_spb_prp_wm_sync);
10111011
dpb += dpb_len;
10121012
buf_len -= dpb_len;
10131013
}
10141014

10151015
#if FB_API_VER >= 40
1016-
const char *compat_buf;
1017-
char compat_buf_size;
1018-
1019-
// ibase_query(): Data type unknown
1020-
// If fbclient >= 4 then convert to VARCHAR at server only INT128 and DECFLOAT
1021-
// If we have older client, convert also timezone types
1022-
if(IBG(client_major_version) >= 4) {
1023-
const char compat[] = "INT128 TO VARCHAR;DECFLOAT TO VARCHAR";
1024-
compat_buf = compat;
1025-
compat_buf_size = sizeof(compat) - 1;
1026-
dpb_len = slprintf(dpb, buf_len, "%c%c%s", isc_dpb_set_bind, compat_buf_size, compat_buf);
1027-
} else {
1028-
const char compat[] = "INT128 TO VARCHAR;DECFLOAT TO VARCHAR;TIME ZONE TO LEGACY";
1029-
compat_buf = compat;
1030-
compat_buf_size = sizeof(compat) - 1;
1031-
dpb_len = slprintf(dpb, buf_len, "%c%c%s", isc_dpb_set_bind, compat_buf_size, compat_buf);
1032-
}
1016+
if (buf_len > 0) {
1017+
// ibase_query(): Data type unknown
1018+
// If fbclient >= 4 then convert to VARCHAR at server only INT128 and DECFLOAT
1019+
// If we have older client, convert also timezone types
1020+
if(IBG(client_major_version) >= 4) {
1021+
const char compat[] = "INT128 TO VARCHAR;DECFLOAT TO VARCHAR";
1022+
dpb_len = snprintf(dpb, buf_len, "%c%c%s", isc_dpb_set_bind, (unsigned char)(sizeof(compat) - 1), compat);
1023+
} else {
1024+
const char compat[] = "INT128 TO VARCHAR;DECFLOAT TO VARCHAR;TIME ZONE TO LEGACY";
1025+
dpb_len = snprintf(dpb, buf_len, "%c%c%s", isc_dpb_set_bind, (unsigned char)(sizeof(compat) - 1), compat);
1026+
}
10331027

1034-
dpb += dpb_len;
1035-
buf_len -= dpb_len;
1028+
dpb += dpb_len;
1029+
buf_len -= dpb_len;
1030+
}
10361031
#endif
10371032

1033+
if (buf_len < 0) {
1034+
fbp_fatal("ibase_connect(): DPB buffer overflow (connection parameters exceed internal buffer size)");
1035+
}
1036+
10381037
if (isc_attach_database(IB_STATUS, (short)len[DB], args[DB], db, (short)(dpb-dpb_buffer), dpb_buffer)) {
10391038
_php_ibase_error();
10401039
return FAILURE;

tests/dpb_buffer_overflow_001.phpt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Connection parameter buffer overflow
3+
--SKIPIF--
4+
<?php include("skipif.inc"); ?>
5+
--FILE--
6+
<?php
7+
8+
require("functions.inc");
9+
set_exception_handler("php_ibase_exception_handler");
10+
11+
(function(){
12+
ibase_connect("bogus", "bogus", "bogus", str_repeat("utf8", 100));
13+
})();
14+
15+
?>
16+
--EXPECTF--
17+
Fatal error: ibase_connect(): DPB buffer overflow (connection parameters exceed internal buffer size) %a

0 commit comments

Comments
 (0)