CVE-2016-1000005: Access of Resource Using Incompatible Type ('Type Confusion') (CWE-843)
value: mcrypt_get_block_size did not enforce that the provided "module" parameter was a string, leading to type confusion if other types of data were passed in. This issue affects HHVM versions prior to 3.9.5, all versions between 3.10.0 and 3.12.3 (inclusive), and all versions between 3.13.0 and 3.14.1 (inclusive).
CWE description: The product allocates or initializes a resource such as a pointer, object, or variable using one type, but it later accesses that resource using a type that is incompatible with the original type.
CVSS v3 base score: 9.8
Published: 2020-02-19T13:15Z
Repository: https://github.com/facebook/hhvm
Language: PHP
Files changed: hphp/runtime/ext/mcrypt/ext_mcrypt.cpp, hphp/runtime/ext/mcrypt/ext_mcrypt.php, hphp/test/slow/ext_mcrypt/ext_mcrypt.php, hphp/test/slow/ext_mcrypt/ext_mcrypt.php.expectf
Commit date: 2016-07-01 09:19:23 -0700
Commit message: Fix param types for mcrypt_get_block_size() to match PHP

Reviewed By: edwinsmith

Differential Revision: D3447281

fbshipit-source-id: a88549307faad886f5a0f78d421aa28e08d21b1c

Diff: diff --git a/hphp/runtime/ext/mcrypt/ext_mcrypt.cpp b/hphp/runtime/ext/mcrypt/ext_mcrypt.cpp
index 0d6f308acf8..4e0413dda60 100644
--- a/hphp/runtime/ext/mcrypt/ext_mcrypt.cpp
+++ b/hphp/runtime/ext/mcrypt/ext_mcrypt.cpp
@@ -455,14 +455,14 @@ Variant HHVM_FUNCTION(mcrypt_ofb, const String& cipher, const String& key,
   return php_mcrypt_do_crypt(cipher, key, data, "ofb", iv, mode.toInt32(),
                              "mcrypt_ofb");
 }
 
 Variant HHVM_FUNCTION(mcrypt_get_block_size, const String& cipher,
-                                    const Variant& module /* = null_string */) {
+                                             const String& mode) {
   MCRYPT td = mcrypt_module_open((char*)cipher.data(),
                                  (char*)MCG(algorithms_dir).data(),
-                                 (char*)module.asCStrRef().data(),
+                                 (char*)mode.data(),
                                  (char*)MCG(modes_dir).data());
   if (td == MCRYPT_FAILED) {
     MCRYPT_OPEN_MODULE_FAILED("mcrypt_get_block_size");
     return false;
   }
diff --git a/hphp/runtime/ext/mcrypt/ext_mcrypt.php b/hphp/runtime/ext/mcrypt/ext_mcrypt.php
index 39c0583fdd4..c447deb77c7 100644
--- a/hphp/runtime/ext/mcrypt/ext_mcrypt.php
+++ b/hphp/runtime/ext/mcrypt/ext_mcrypt.php
@@ -295,11 +295,11 @@ function mcrypt_generic(resource $td,
  *
  * @return int - Gets the block size, as an integer.
  */
 <<__Native>>
 function mcrypt_get_block_size(string $cipher,
-                               ?string $mode = null): mixed;
+                               string $mode): mixed;
 
 /**
  * Gets the name of the specified cipher
  *
  * @param string $cipher -
diff --git a/hphp/test/slow/ext_mcrypt/ext_mcrypt.php b/hphp/test/slow/ext_mcrypt/ext_mcrypt.php
index d55dc9f0e63..d44ebd148c7 100644
--- a/hphp/test/slow/ext_mcrypt/ext_mcrypt.php
+++ b/hphp/test/slow/ext_mcrypt/ext_mcrypt.php
@@ -104,10 +104,11 @@ VERIFY($encrypted !== $decrypted);
 VS($decrypted, $CC);
 
 //////////////////////////////////////////////////////////////////////
 
 VS(mcrypt_get_block_size("tripledes", "ecb"), 8);
+mcrypt_get_block_size("tripledes");
 VS(mcrypt_get_cipher_name(MCRYPT_TRIPLEDES), "3DES");
 VS(mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CFB), 16);
 VS(mcrypt_get_iv_size("des", "ecb"), 8);
 VS(mcrypt_get_key_size("tripledes", "ecb"), 24);
 
diff --git a/hphp/test/slow/ext_mcrypt/ext_mcrypt.php.expectf b/hphp/test/slow/ext_mcrypt/ext_mcrypt.php.expectf
index bdfd53d2ba4..4d3ac560b89 100644
--- a/hphp/test/slow/ext_mcrypt/ext_mcrypt.php.expectf
+++ b/hphp/test/slow/ext_mcrypt/ext_mcrypt.php.expectf
@@ -36,10 +36,12 @@ Deprecated: Function mcrypt_ofb() is deprecated in %s/test/slow/ext_mcrypt/ext_m
 
 Deprecated: Function mcrypt_ofb() is deprecated in %s/test/slow/ext_mcrypt/ext_mcrypt.php on line 102
 bool(true)
 bool(true)
 bool(true)
+
+Warning: mcrypt_get_block_size() expects exactly 2 parameters, 1 given in %s/test/slow/ext_mcrypt/ext_mcrypt.php on line 109
 bool(true)
 bool(true)
 bool(true)
 bool(true)
 bool(true)

Vulnerable code:                                     const Variant& module /* = null_string */) {
                                 (char*)module.asCStrRef().data(),
                               ?string $mode = null): mixed;
Fixed code:                                              const String& mode) {
                                 (char*)mode.data(),
                               string $mode): mixed;
mcrypt_get_block_size("tripledes");

Warning: mcrypt_get_block_size() expects exactly 2 parameters, 1 given in %s/test/slow/ext_mcrypt/ext_mcrypt.php on line 109