]> granicus.if.org Git - php/commitdiff
Fixed bug #74625 (Integer overflow in oci_bind_array_by_name).
authorIngmar Runge <ingmar.runge@sixt.com>
Mon, 22 May 2017 06:58:18 +0000 (08:58 +0200)
committerChristopher Jones <sixd@php.net>
Wed, 21 Jun 2017 05:44:55 +0000 (15:44 +1000)
NEWS
ext/oci8/oci8_statement.c
ext/oci8/tests/bug74625.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 6e3496c020beb362fed330b809ac81019bea06e8..f2a907b7c4640c1caa4150bccc1284295212499f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -26,7 +26,8 @@ PHP                                                                        NEWS
     CVE-2017-9228, CVE-2017-9229) (Remi, Mamoru TASAKA)
 
 - OCI8:
- . Add TAF callback (PR #2459). (KoenigsKind)
+  . Add TAF callback (PR #2459). (KoenigsKind)
+  . Fixed bug #74625 (Integer overflow in oci_bind_array_by_name). (Ingmar Runge)
 
 - Opcache:
   . Fixed bug #74663 (Segfault with opcache.memory_protect and
@@ -2527,4 +2528,3 @@ PHP                                                                        NEWS
   . Update bundled libzip to 1.0.1. (Remi, Anatol)
   . Fixed bug #67161 (ZipArchive::getStream() returns NULL for certain file).
     (Christoph M. Becker)
-
index 467e2689dc9df4fc259b0395b286c67d05317e66..470d8d0d9400364f7e036ff42dd6373e42f5a4bf 100644 (file)
 #include "php_oci8.h"
 #include "php_oci8_int.h"
 
+#if defined(OCI_MAJOR_VERSION) && (OCI_MAJOR_VERSION > 10) && \
+       (defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64))
+typedef ub8 oci_phpsized_int;
+#else
+typedef ub4 oci_phpsized_int;
+#endif
+
 /* {{{ php_oci_statement_create()
  Create statemend handle and allocate necessary resources */
 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)
                                for (i = 0; i < (int) bind->array.current_length; i++) {
                                        if ((i < (int) bind->array.old_length) && (entry = zend_hash_get_current_data(hash)) != NULL) {
                                                zval_dtor(entry);
-                                               ZVAL_LONG(entry, ((ub4 *)(bind->array.elements))[i]);
+                                               ZVAL_LONG(entry, ((oci_phpsized_int *)(bind->array.elements))[i]);
                                                zend_hash_move_forward(hash);
                                        } else {
-                                               add_next_index_long(bind->zval, ((ub4 *)(bind->array.elements))[i]);
+                                               add_next_index_long(bind->zval, ((oci_phpsized_int *)(bind->array.elements))[i]);
                                        }
                                }
                                break;
@@ -1153,14 +1160,8 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l
                                return 1;
                        }
                        convert_to_long(param);
-#if defined(OCI_MAJOR_VERSION) && (OCI_MAJOR_VERSION > 10) &&                  \
-       (defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)) 
-                       bind_data = (ub8 *)&Z_LVAL_P(param);
-                       value_sz = sizeof(ub8);
-#else
-                       bind_data = (ub4 *)&Z_LVAL_P(param);
-                       value_sz = sizeof(ub4);
-#endif
+                       bind_data = (oci_phpsized_int *)&Z_LVAL_P(param);
+                       value_sz = sizeof(oci_phpsized_int);
                        mode = OCI_DEFAULT;
                        break;
                        
@@ -1783,10 +1784,10 @@ php_oci_bind *php_oci_bind_array_helper_number(zval *var, zend_long max_table_le
 
        bind = emalloc(sizeof(php_oci_bind));
        ZVAL_UNDEF(&bind->parameter);
-       bind->array.elements            = (ub4 *)safe_emalloc(max_table_length, sizeof(ub4), 0);
+       bind->array.elements            = (oci_phpsized_int *)safe_emalloc(max_table_length, sizeof(oci_phpsized_int), 0);
        bind->array.current_length      = zend_hash_num_elements(Z_ARRVAL_P(var));
        bind->array.old_length          = bind->array.current_length;
-       bind->array.max_length          = sizeof(ub4);
+       bind->array.max_length          = sizeof(oci_phpsized_int);
        bind->array.element_lengths     = safe_emalloc(max_table_length, sizeof(ub2), 0);
        memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
        bind->array.indicators          = NULL;
@@ -1794,14 +1795,14 @@ php_oci_bind *php_oci_bind_array_helper_number(zval *var, zend_long max_table_le
        zend_hash_internal_pointer_reset(hash);
        for (i = 0; i < max_table_length; i++) {
                if (i < bind->array.current_length) {
-                       bind->array.element_lengths[i] = sizeof(ub4);
+                       bind->array.element_lengths[i] = sizeof(oci_phpsized_int);
                }
                if ((i < bind->array.current_length) && (entry = zend_hash_get_current_data(hash)) != NULL) {
                        convert_to_long_ex(entry);
-                       ((ub4 *)bind->array.elements)[i] = (ub4) Z_LVAL_P(entry);
+                       ((oci_phpsized_int *)bind->array.elements)[i] = (oci_phpsized_int) Z_LVAL_P(entry);
                        zend_hash_move_forward(hash);
                } else {
-                       ((ub4 *)bind->array.elements)[i] = 0;
+                       ((oci_phpsized_int *)bind->array.elements)[i] = 0;
                }
        }
        zend_hash_internal_pointer_reset(hash);
diff --git a/ext/oci8/tests/bug74625.phpt b/ext/oci8/tests/bug74625.phpt
new file mode 100644 (file)
index 0000000..7b6c316
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Bug #74625 (Integer overflow in oci_bind_array_by_name)
+--SKIPIF--
+<?php
+if (!extension_loaded('oci8')) die ("skip no oci8 extension");
+if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platforms only");
+?>
+--FILE--
+<?php
+
+require(dirname(__FILE__).'/connect.inc');
+
+$s = oci_parse($c, "BEGIN
+      SELECT -1 BULK COLLECT INTO :a FROM DUAL;
+  END;");
+oci_bind_array_by_name($s, ':a', $a, 5000, 10, SQLT_INT);
+oci_execute($s);
+
+var_dump($a);
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+Array
+(
+    [0] => -1
+)
+===DONE===