From 5fc24c19a6da46e4ce0d1be7a1c4c6538f3ec75e Mon Sep 17 00:00:00 2001 From: yang_zhuang_zhuang <1162011203@qq.com> Date: Wed, 3 Feb 2021 10:21:26 +0800 Subject: [PATCH] Fix CVE-2020-7069 CVE-2020-7070 --- ...ong-ciphertext-tag-in-AES-CCM-encryp.patch | 158 ++++++++++++++++++ ...0-Do-not-decode-cookie-names-anymore.patch | 115 +++++++++++++ ...enssl_encrypt_ccm.phpt-fails-with-op.patch | 56 +++++++ php.spec | 8 +- 4 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2020-7069-Fix-bug-79601-Wrong-ciphertext-tag-in-AES-CCM-encryp.patch create mode 100644 backport-CVE-2020-7070-Do-not-decode-cookie-names-anymore.patch create mode 100644 backport-Fix-bug-78079-openssl_encrypt_ccm.phpt-fails-with-op.patch diff --git a/backport-CVE-2020-7069-Fix-bug-79601-Wrong-ciphertext-tag-in-AES-CCM-encryp.patch b/backport-CVE-2020-7069-Fix-bug-79601-Wrong-ciphertext-tag-in-AES-CCM-encryp.patch new file mode 100644 index 0000000..6818edd --- /dev/null +++ b/backport-CVE-2020-7069-Fix-bug-79601-Wrong-ciphertext-tag-in-AES-CCM-encryp.patch @@ -0,0 +1,158 @@ +From 0216630ea2815a5789a24279a1211ac398d4de79 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sat, 26 Sep 2020 22:08:52 -0700 +Subject: [PATCH] Fix bug #79601 (Wrong ciphertext/tag in AES-CCM encryption + for a 12 bytes IV) + +--- + ext/openssl/openssl.c | 10 ++++----- + ext/openssl/tests/cipher_tests.inc | 21 +++++++++++++++++ + ext/openssl/tests/openssl_decrypt_ccm.phpt | 22 +++++++++++------- + ext/openssl/tests/openssl_encrypt_ccm.phpt | 26 ++++++++++++++-------- + 4 files changed, 57 insertions(+), 22 deletions(-) + +diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c +index 6c1dd9d3435d..3eea08c64901 100644 +--- a/ext/openssl/openssl.c ++++ b/ext/openssl/openssl.c +@@ -6391,11 +6391,6 @@ static int php_openssl_validate_iv(char **piv, size_t *piv_len, size_t iv_requir + { + char *iv_new; + +- /* Best case scenario, user behaved */ +- if (*piv_len == iv_required_len) { +- return SUCCESS; +- } +- + if (mode->is_aead) { + if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_ivlen_flag, *piv_len, NULL) != 1) { + php_error_docref(NULL, E_WARNING, "Setting of IV length for AEAD mode failed"); +@@ -6404,6 +6399,11 @@ static int php_openssl_validate_iv(char **piv, size_t *piv_len, size_t iv_requir + return SUCCESS; + } + ++ /* Best case scenario, user behaved */ ++ if (*piv_len == iv_required_len) { ++ return SUCCESS; ++ } ++ + iv_new = ecalloc(1, iv_required_len + 1); + + if (*piv_len == 0) { +diff --git a/ext/openssl/tests/cipher_tests.inc b/ext/openssl/tests/cipher_tests.inc +index b1e46b411e54..779bfa8515cb 100644 +--- a/ext/openssl/tests/cipher_tests.inc ++++ b/ext/openssl/tests/cipher_tests.inc +@@ -1,5 +1,26 @@ + array( ++ array( ++ 'key' => '404142434445464748494a4b4c4d4e4f', ++ 'iv' => '1011121314151617', ++ 'aad' => '000102030405060708090a0b0c0d0e0f', ++ 'tag' => '1fc64fbfaccd', ++ 'pt' => '202122232425262728292a2b2c2d2e2f', ++ 'ct' => 'd2a1f0e051ea5f62081a7792073d593d', ++ ), ++ array( ++ 'key' => '404142434445464748494a4b4c4d4e4f', ++ 'iv' => '101112131415161718191a1b', ++ 'aad' => '000102030405060708090a0b0c0d0e0f' . ++ '10111213', ++ 'tag' => '484392fbc1b09951', ++ 'pt' => '202122232425262728292a2b2c2d2e2f' . ++ '3031323334353637', ++ 'ct' => 'e3b201a9f5b71a7a9b1ceaeccd97e70b' . ++ '6176aad9a4428aa5', ++ ), ++ ), + 'aes-256-ccm' => array( + array( + 'key' => '1bde3251d41a8b5ea013c195ae128b21' . +diff --git a/ext/openssl/tests/openssl_decrypt_ccm.phpt b/ext/openssl/tests/openssl_decrypt_ccm.phpt +index a5f01b87cea8..08ef5bb7b7c4 100644 +--- a/ext/openssl/tests/openssl_decrypt_ccm.phpt ++++ b/ext/openssl/tests/openssl_decrypt_ccm.phpt +@@ -10,14 +10,16 @@ if (!in_array('aes-256-ccm', openssl_get_cipher_methods())) + --FILE-- + $test) { +- echo "TEST $idx\n"; +- $pt = openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, +- $test['iv'], $test['tag'], $test['aad']); +- var_dump($test['pt'] === $pt); ++foreach ($methods as $method) { ++ $tests = openssl_get_cipher_tests($method); ++ foreach ($tests as $idx => $test) { ++ echo "$method - TEST $idx\n"; ++ $pt = openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, ++ $test['iv'], $test['tag'], $test['aad']); ++ var_dump($test['pt'] === $pt); ++ } + } + + // no IV +@@ -32,7 +34,11 @@ var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, + + ?> + --EXPECTF-- +-TEST 0 ++aes-128-ccm - TEST 0 ++bool(true) ++aes-128-ccm - TEST 1 ++bool(true) ++aes-256-ccm - TEST 0 + bool(true) + + Warning: openssl_decrypt(): Setting of IV length for AEAD mode failed in %s on line %d +diff --git a/ext/openssl/tests/openssl_encrypt_ccm.phpt b/ext/openssl/tests/openssl_encrypt_ccm.phpt +index fb5dbbc849d0..8c4c41f81870 100644 +--- a/ext/openssl/tests/openssl_encrypt_ccm.phpt ++++ b/ext/openssl/tests/openssl_encrypt_ccm.phpt +@@ -10,15 +10,17 @@ if (!in_array('aes-256-ccm', openssl_get_cipher_methods())) + --FILE-- + $test) { +- echo "TEST $idx\n"; +- $ct = openssl_encrypt($test['pt'], $method, $test['key'], OPENSSL_RAW_DATA, +- $test['iv'], $tag, $test['aad'], strlen($test['tag'])); +- var_dump($test['ct'] === $ct); +- var_dump($test['tag'] === $tag); ++foreach ($methods as $method) { ++ $tests = openssl_get_cipher_tests($method); ++ foreach ($tests as $idx => $test) { ++ echo "$method - TEST $idx\n"; ++ $ct = openssl_encrypt($test['pt'], $method, $test['key'], OPENSSL_RAW_DATA, ++ $test['iv'], $tag, $test['aad'], strlen($test['tag'])); ++ var_dump($test['ct'] === $ct); ++ var_dump($test['tag'] === $tag); ++ } + } + + // Empty IV error +@@ -32,7 +34,13 @@ var_dump(strlen($tag)); + var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 16), $tag, '', 1024)); + ?> + --EXPECTF-- +-TEST 0 ++aes-128-ccm - TEST 0 ++bool(true) ++bool(true) ++aes-128-ccm - TEST 1 ++bool(true) ++bool(true) ++aes-256-ccm - TEST 0 + bool(true) + bool(true) + diff --git a/backport-CVE-2020-7070-Do-not-decode-cookie-names-anymore.patch b/backport-CVE-2020-7070-Do-not-decode-cookie-names-anymore.patch new file mode 100644 index 0000000..c508d5e --- /dev/null +++ b/backport-CVE-2020-7070-Do-not-decode-cookie-names-anymore.patch @@ -0,0 +1,115 @@ +From 6559fe912661ca5ce5f0eeeb591d928451428ed0 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sun, 20 Sep 2020 18:08:55 -0700 +Subject: [PATCH] Do not decode cookie names anymore + +--- + main/php_variables.c | 8 ++++++-- + tests/basic/022.phpt | 10 +++++++--- + tests/basic/023.phpt | 4 +++- + tests/basic/bug79699.phpt | 22 ++++++++++++++++++++++ + 4 files changed, 38 insertions(+), 6 deletions(-) + create mode 100644 tests/basic/bug79699.phpt + +diff --git a/main/php_variables.c b/main/php_variables.c +index 916fc1295b4c..097c17d32afe 100644 +--- a/main/php_variables.c ++++ b/main/php_variables.c +@@ -492,7 +492,9 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) + size_t new_val_len; + + *val++ = '\0'; +- php_url_decode(var, strlen(var)); ++ if (arg != PARSE_COOKIE) { ++ php_url_decode(var, strlen(var)); ++ } + val_len = php_url_decode(val, strlen(val)); + val = estrndup(val, val_len); + if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) { +@@ -503,7 +505,9 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) + size_t val_len; + size_t new_val_len; + +- php_url_decode(var, strlen(var)); ++ if (arg != PARSE_COOKIE) { ++ php_url_decode(var, strlen(var)); ++ } + val_len = 0; + val = estrndup("", val_len); + if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) { +diff --git a/tests/basic/022.phpt b/tests/basic/022.phpt +index 0ab70d4be764..bd1db1370182 100644 +--- a/tests/basic/022.phpt ++++ b/tests/basic/022.phpt +@@ -10,7 +10,7 @@ cookie1=val1 ; cookie2=val2%20; cookie3=val 3.; cookie 4= value 4 %3B; cookie1= + var_dump($_COOKIE); + ?> + --EXPECT-- +-array(10) { ++array(12) { + ["cookie1"]=> + string(6) "val1 " + ["cookie2"]=> +@@ -19,11 +19,15 @@ array(10) { + string(6) "val 3." + ["cookie_4"]=> + string(10) " value 4 ;" ++ ["%20cookie1"]=> ++ string(6) "ignore" ++ ["+cookie1"]=> ++ string(6) "ignore" + ["cookie__5"]=> + string(7) " value" +- ["cookie_6"]=> ++ ["cookie%206"]=> + string(3) "þæö" +- ["cookie_7"]=> ++ ["cookie+7"]=> + string(0) "" + ["$cookie_8"]=> + string(0) "" +diff --git a/tests/basic/023.phpt b/tests/basic/023.phpt +index ca5f1dcfbb1a..0e2e0ac66945 100644 +--- a/tests/basic/023.phpt ++++ b/tests/basic/023.phpt +@@ -10,9 +10,11 @@ c o o k i e=value; c o o k i e= v a l u e ;;c%20o+o k+i%20e=v;name="value","valu + var_dump($_COOKIE); + ?> + --EXPECT-- +-array(3) { ++array(4) { + ["c_o_o_k_i_e"]=> + string(5) "value" ++ ["c%20o+o_k+i%20e"]=> ++ string(1) "v" + ["name"]=> + string(24) ""value","value",UEhQIQ==" + ["UEhQIQ"]=> +diff --git a/tests/basic/bug79699.phpt b/tests/basic/bug79699.phpt +new file mode 100644 +index 000000000000..fc3d3fedb08f +--- /dev/null ++++ b/tests/basic/bug79699.phpt +@@ -0,0 +1,22 @@ ++--TEST-- ++Cookies Security Bug ++--INI-- ++max_input_vars=1000 ++filter.default=unsafe_raw ++--COOKIE-- ++__%48ost-evil=evil; __Host-evil=good; %66oo=baz;foo=bar ++--FILE-- ++ ++--EXPECT-- ++array(4) { ++ ["__%48ost-evil"]=> ++ string(4) "evil" ++ ["__Host-evil"]=> ++ string(4) "good" ++ ["%66oo"]=> ++ string(3) "baz" ++ ["foo"]=> ++ string(3) "bar" ++} diff --git a/backport-Fix-bug-78079-openssl_encrypt_ccm.phpt-fails-with-op.patch b/backport-Fix-bug-78079-openssl_encrypt_ccm.phpt-fails-with-op.patch new file mode 100644 index 0000000..2e80ed3 --- /dev/null +++ b/backport-Fix-bug-78079-openssl_encrypt_ccm.phpt-fails-with-op.patch @@ -0,0 +1,56 @@ +From 2e025794745e09f7d0c72822ad0238bf6d67b2e8 Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka +Date: Sun, 2 Jun 2019 19:10:56 +0100 +Subject: [PATCH] Fix bug #78079 (openssl_encrypt_ccm.phpt fails with OpenSSL + 1.1.1c) + +It also fixes invalid setting of tag length +--- + ext/openssl/openssl.c | 5 ++++- + ext/openssl/tests/openssl_encrypt_ccm.phpt | 12 +++++++++--- + 3 files changed, 17 insertions(+), 4 deletions(-) + +diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c +index 7df50720eb12..91df229c3d45 100644 +--- a/ext/openssl/openssl.c ++++ b/ext/openssl/openssl.c +@@ -6444,7 +6444,10 @@ static int php_openssl_cipher_init(const EVP_CIPHER *cipher_type, + return FAILURE; + } + if (mode->is_single_run_aead && enc) { +- EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, NULL); ++ if (!EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, NULL)) { ++ php_error_docref(NULL, E_WARNING, "Setting tag length for AEAD cipher failed"); ++ return FAILURE; ++ } + } else if (!enc && tag && tag_len > 0) { + if (!mode->is_aead) { + php_error_docref(NULL, E_WARNING, "The tag cannot be used because the cipher method does not support AEAD"); +diff --git a/ext/openssl/tests/openssl_encrypt_ccm.phpt b/ext/openssl/tests/openssl_encrypt_ccm.phpt +index c8610bc96bc4..fb5dbbc849d0 100644 +--- a/ext/openssl/tests/openssl_encrypt_ccm.phpt ++++ b/ext/openssl/tests/openssl_encrypt_ccm.phpt +@@ -24,9 +24,12 @@ foreach ($tests as $idx => $test) { + // Empty IV error + var_dump(openssl_encrypt('data', $method, 'password', 0, NULL, $tag, '')); + +-// Test setting different IV length and unlimeted tag +-var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 10), $tag, '', 1024)); ++// Test setting different IV length and tag length ++var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 10), $tag, '', 14)); + var_dump(strlen($tag)); ++ ++// Test setting invalid tag length ++var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 16), $tag, '', 1024)); + ?> + --EXPECTF-- + TEST 0 +@@ -36,4 +39,7 @@ bool(true) + Warning: openssl_encrypt(): Setting of IV length for AEAD mode failed in %s on line %d + bool(false) + string(8) "p/lvgA==" +-int(1024) ++int(14) ++ ++Warning: openssl_encrypt(): Setting of IV length for AEAD mode failed in %s on line %d ++bool(false) diff --git a/php.spec b/php.spec index ab444f1..d2b3bec 100644 --- a/php.spec +++ b/php.spec @@ -28,7 +28,7 @@ Name: php Version: %{upver}%{?rcver:~%{rcver}} -Release: 11 +Release: 12 Summary: PHP scripting language for creating dynamic web sites License: PHP and Zend and BSD and MIT and ASL 1.0 and NCSA URL: http://www.php.net/ @@ -98,6 +98,9 @@ Patch6027: backport-CVE-2020-7059-Fix-79099-OOB-read.patch Patch6028: backport-CVE-2020-7062-Fix-bug-79221.patch Patch6029: backport-CVE-2020-7071-Fix-bug-77423.patch Patch6030: backport-CVE-2020-7060-Fix-bug-79037-global-buffer-overflow-in-mbfl_filt_co.patch +Patch6031: backport-Fix-bug-78079-openssl_encrypt_ccm.phpt-fails-with-op.patch +Patch6032: backport-CVE-2020-7069-Fix-bug-79601-Wrong-ciphertext-tag-in-AES-CCM-encryp.patch +Patch6033: backport-CVE-2020-7070-Do-not-decode-cookie-names-anymore.patch BuildRequires: bzip2-devel, curl-devel >= 7.9, httpd-devel >= 2.0.46-1, pam-devel, httpd-filesystem, nginx-filesystem BuildRequires: libstdc++-devel, openssl-devel, sqlite-devel >= 3.6.0, zlib-devel, smtpdaemon, libedit-devel @@ -1158,6 +1161,9 @@ systemctl try-restart php-fpm.service >/dev/null 2>&1 || : %changelog +* Wed Feb 3 2021 yangzhuangzhuang - 7.2.10-12 +- Fix CVE-2020-7069 CVE-2020-7070 + * Tue Feb 2 2021 yangzhuangzhuang - 7.2.10-11 - Fix CVE-2020-7060 -- Gitee