Skip to content

Commit fa3615f

Browse files
KiNgMaRcjbj
authored andcommitted
Fixed bug #74625 (Integer overflow in oci_bind_array_by_name).
1 parent 3fbbcf7 commit fa3615f

File tree

3 files changed

+46
-17
lines changed

3 files changed

+46
-17
lines changed

NEWS

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ PHP NEWS
2626
CVE-2017-9228, CVE-2017-9229) (Remi, Mamoru TASAKA)
2727

2828
- OCI8:
29-
. Add TAF callback (PR #2459). (KoenigsKind)
29+
. Add TAF callback (PR #2459). (KoenigsKind)
30+
. Fixed bug #74625 (Integer overflow in oci_bind_array_by_name). (Ingmar Runge)
3031

3132
- Opcache:
3233
. Fixed bug #74663 (Segfault with opcache.memory_protect and
@@ -2527,4 +2528,3 @@ PHP NEWS
25272528
. Update bundled libzip to 1.0.1. (Remi, Anatol)
25282529
. Fixed bug #67161 (ZipArchive::getStream() returns NULL for certain file).
25292530
(Christoph M. Becker)
2530-

ext/oci8/oci8_statement.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
#include "php_oci8.h"
3939
#include "php_oci8_int.h"
4040

41+
#if defined(OCI_MAJOR_VERSION) && (OCI_MAJOR_VERSION > 10) && \
42+
(defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64))
43+
typedef ub8 oci_phpsized_int;
44+
#else
45+
typedef ub4 oci_phpsized_int;
46+
#endif
47+
4148
/* {{{ php_oci_statement_create()
4249
Create statemend handle and allocate necessary resources */
4350
php_oci_statement *php_oci_statement_create(php_oci_connection *connection, char *query, int query_len)
@@ -997,10 +1004,10 @@ int php_oci_bind_post_exec(zval *data)
9971004
for (i = 0; i < (int) bind->array.current_length; i++) {
9981005
if ((i < (int) bind->array.old_length) && (entry = zend_hash_get_current_data(hash)) != NULL) {
9991006
zval_dtor(entry);
1000-
ZVAL_LONG(entry, ((ub4 *)(bind->array.elements))[i]);
1007+
ZVAL_LONG(entry, ((oci_phpsized_int *)(bind->array.elements))[i]);
10011008
zend_hash_move_forward(hash);
10021009
} else {
1003-
add_next_index_long(bind->zval, ((ub4 *)(bind->array.elements))[i]);
1010+
add_next_index_long(bind->zval, ((oci_phpsized_int *)(bind->array.elements))[i]);
10041011
}
10051012
}
10061013
break;
@@ -1153,14 +1160,8 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l
11531160
return 1;
11541161
}
11551162
convert_to_long(param);
1156-
#if defined(OCI_MAJOR_VERSION) && (OCI_MAJOR_VERSION > 10) && \
1157-
(defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64))
1158-
bind_data = (ub8 *)&Z_LVAL_P(param);
1159-
value_sz = sizeof(ub8);
1160-
#else
1161-
bind_data = (ub4 *)&Z_LVAL_P(param);
1162-
value_sz = sizeof(ub4);
1163-
#endif
1163+
bind_data = (oci_phpsized_int *)&Z_LVAL_P(param);
1164+
value_sz = sizeof(oci_phpsized_int);
11641165
mode = OCI_DEFAULT;
11651166
break;
11661167

@@ -1783,25 +1784,25 @@ php_oci_bind *php_oci_bind_array_helper_number(zval *var, zend_long max_table_le
17831784

17841785
bind = emalloc(sizeof(php_oci_bind));
17851786
ZVAL_UNDEF(&bind->parameter);
1786-
bind->array.elements = (ub4 *)safe_emalloc(max_table_length, sizeof(ub4), 0);
1787+
bind->array.elements = (oci_phpsized_int *)safe_emalloc(max_table_length, sizeof(oci_phpsized_int), 0);
17871788
bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var));
17881789
bind->array.old_length = bind->array.current_length;
1789-
bind->array.max_length = sizeof(ub4);
1790+
bind->array.max_length = sizeof(oci_phpsized_int);
17901791
bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0);
17911792
memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
17921793
bind->array.indicators = NULL;
17931794

17941795
zend_hash_internal_pointer_reset(hash);
17951796
for (i = 0; i < max_table_length; i++) {
17961797
if (i < bind->array.current_length) {
1797-
bind->array.element_lengths[i] = sizeof(ub4);
1798+
bind->array.element_lengths[i] = sizeof(oci_phpsized_int);
17981799
}
17991800
if ((i < bind->array.current_length) && (entry = zend_hash_get_current_data(hash)) != NULL) {
18001801
convert_to_long_ex(entry);
1801-
((ub4 *)bind->array.elements)[i] = (ub4) Z_LVAL_P(entry);
1802+
((oci_phpsized_int *)bind->array.elements)[i] = (oci_phpsized_int) Z_LVAL_P(entry);
18021803
zend_hash_move_forward(hash);
18031804
} else {
1804-
((ub4 *)bind->array.elements)[i] = 0;
1805+
((oci_phpsized_int *)bind->array.elements)[i] = 0;
18051806
}
18061807
}
18071808
zend_hash_internal_pointer_reset(hash);

ext/oci8/tests/bug74625.phpt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Bug #74625 (Integer overflow in oci_bind_array_by_name)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('oci8')) die ("skip no oci8 extension");
6+
if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platforms only");
7+
?>
8+
--FILE--
9+
<?php
10+
11+
require(dirname(__FILE__).'/connect.inc');
12+
13+
$s = oci_parse($c, "BEGIN
14+
SELECT -1 BULK COLLECT INTO :a FROM DUAL;
15+
END;");
16+
oci_bind_array_by_name($s, ':a', $a, 5000, 10, SQLT_INT);
17+
oci_execute($s);
18+
19+
var_dump($a);
20+
?>
21+
===DONE===
22+
<?php exit(0); ?>
23+
--EXPECTF--
24+
Array
25+
(
26+
[0] => -1
27+
)
28+
===DONE===

0 commit comments

Comments
 (0)