commit:     280c5e27b96f27eed2f3325576d74361abb36294
Author:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 23 00:38:40 2020 +0000
Commit:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Dec 23 00:39:05 2020 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=280c5e27

dev-lang/php: fix use-after-free when accessing already destructed backtrace 
arguments

Bug: https://bugs.gentoo.org/711140
Package-Manager: Portage-3.0.12, Repoman-3.0.2
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>

 .../files/php-7.2.34-use-after-free-bug76047.patch | 174 +++++++++++++++++++++
 .../{php-7.2.34.ebuild => php-7.2.34-r1.ebuild}    |   1 +
 2 files changed, 175 insertions(+)

diff --git a/dev-lang/php/files/php-7.2.34-use-after-free-bug76047.patch 
b/dev-lang/php/files/php-7.2.34-use-after-free-bug76047.patch
new file mode 100644
index 00000000000..b3a864ee82a
--- /dev/null
+++ b/dev-lang/php/files/php-7.2.34-use-after-free-bug76047.patch
@@ -0,0 +1,174 @@
+Backport of 
https://git.php.net/?p=php-src.git;a=commit;h=ef1e4891b47949c8dc0f9482eef9454a0ecdfa1d
+
+--- a/Zend/tests/bug52361.phpt
++++ b/Zend/tests/bug52361.phpt
+@@ -25,9 +25,8 @@ try {
+ --EXPECTF--
+ 1. Exception: aaa in %sbug52361.php:5
+ Stack trace:
+-#0 %sbug52361.php(13): aaa->__destruct()
+-#1 %sbug52361.php(16): bbb()
+-#2 {main}
++#0 %sbug52361.php(16): aaa->__destruct()
++#1 {main}
+ 2. Exception: bbb in %sbug52361.php:13
+ Stack trace:
+ #0 %sbug52361.php(16): bbb()
+--- /dev/null
++++ b/Zend/tests/bug76047.phpt
+@@ -0,0 +1,68 @@
++--TEST--
++Bug #76047: Use-after-free when accessing already destructed backtrace 
arguments
++--FILE--
++<?php
++
++class Vuln {
++    public $a;
++    public function __destruct() {
++        unset($this->a);
++        $backtrace = (new Exception)->getTrace();
++        var_dump($backtrace);
++    }
++}
++
++function test($arg) {
++    $arg = str_shuffle(str_repeat('A', 79));
++    $vuln = new Vuln();
++    $vuln->a = $arg;
++}
++
++function test2($arg) {
++    $$arg = 1; // Trigger symbol table
++    $arg = str_shuffle(str_repeat('A', 79));
++    $vuln = new Vuln();
++    $vuln->a = $arg;
++}
++
++test('x');
++test2('x');
++
++?>
++--EXPECTF--
++array(1) {
++  [0]=>
++  array(6) {
++    ["file"]=>
++    string(%d) "%s"
++    ["line"]=>
++    int(%d)
++    ["function"]=>
++    string(10) "__destruct"
++    ["class"]=>
++    string(4) "Vuln"
++    ["type"]=>
++    string(2) "->"
++    ["args"]=>
++    array(0) {
++    }
++  }
++}
++array(1) {
++  [0]=>
++  array(6) {
++    ["file"]=>
++    string(%d) "%s"
++    ["line"]=>
++    int(%d)
++    ["function"]=>
++    string(10) "__destruct"
++    ["class"]=>
++    string(4) "Vuln"
++    ["type"]=>
++    string(2) "->"
++    ["args"]=>
++    array(0) {
++    }
++  }
++}
+--- a/Zend/zend_vm_def.h
++++ b/Zend/zend_vm_def.h
+@@ -2366,9 +2366,9 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
+       uint32_t call_info = EX_CALL_INFO();
+ 
+       if (EXPECTED((call_info & 
(ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED))
 == 0)) {
++              EG(current_execute_data) = EX(prev_execute_data);
+               i_free_compiled_variables(execute_data);
+ 
+-              EG(current_execute_data) = EX(prev_execute_data);
+               if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
+                       zend_object *object = Z_OBJ(execute_data->This);
+ #if 0
+@@ -2394,12 +2394,12 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
+               LOAD_NEXT_OPLINE();
+               ZEND_VM_LEAVE();
+       } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) 
{
++              EG(current_execute_data) = EX(prev_execute_data);
+               i_free_compiled_variables(execute_data);
+ 
+               if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
+                       zend_clean_and_cache_symbol_table(EX(symbol_table));
+               }
+-              EG(current_execute_data) = EX(prev_execute_data);
+ 
+               /* Free extra args before releasing the closure,
+                * as that may free the op_array. */
+@@ -2449,6 +2449,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
+               ZEND_VM_LEAVE();
+       } else {
+               if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
++                      EG(current_execute_data) = EX(prev_execute_data);
+                       i_free_compiled_variables(execute_data);
+                       if (UNEXPECTED(call_info & 
(ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
+                               if (UNEXPECTED(call_info & 
ZEND_CALL_HAS_SYMBOL_TABLE)) {
+@@ -2456,7 +2457,6 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
+                               }
+                               zend_vm_stack_free_extra_args_ex(call_info, 
execute_data);
+                       }
+-                      EG(current_execute_data) = EX(prev_execute_data);
+                       if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
+                               
OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
+                       }
+--- a/Zend/zend_vm_execute.h
++++ b/Zend/zend_vm_execute.h
+@@ -434,9 +434,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL 
zend_leave_helper_SPEC(ZEND_OPCODE_
+       uint32_t call_info = EX_CALL_INFO();
+ 
+       if (EXPECTED((call_info & 
(ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED))
 == 0)) {
++              EG(current_execute_data) = EX(prev_execute_data);
+               i_free_compiled_variables(execute_data);
+ 
+-              EG(current_execute_data) = EX(prev_execute_data);
+               if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
+                       zend_object *object = Z_OBJ(execute_data->This);
+ #if 0
+@@ -462,12 +462,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL 
zend_leave_helper_SPEC(ZEND_OPCODE_
+               LOAD_NEXT_OPLINE();
+               ZEND_VM_LEAVE();
+       } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) 
{
++              EG(current_execute_data) = EX(prev_execute_data);
+               i_free_compiled_variables(execute_data);
+ 
+               if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
+                       zend_clean_and_cache_symbol_table(EX(symbol_table));
+               }
+-              EG(current_execute_data) = EX(prev_execute_data);
+ 
+               /* Free extra args before releasing the closure,
+                * as that may free the op_array. */
+@@ -517,6 +517,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL 
zend_leave_helper_SPEC(ZEND_OPCODE_
+               ZEND_VM_LEAVE();
+       } else {
+               if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
++                      EG(current_execute_data) = EX(prev_execute_data);
+                       i_free_compiled_variables(execute_data);
+                       if (UNEXPECTED(call_info & 
(ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
+                               if (UNEXPECTED(call_info & 
ZEND_CALL_HAS_SYMBOL_TABLE)) {
+@@ -524,7 +525,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL 
zend_leave_helper_SPEC(ZEND_OPCODE_
+                               }
+                               zend_vm_stack_free_extra_args_ex(call_info, 
execute_data);
+                       }
+-                      EG(current_execute_data) = EX(prev_execute_data);
+                       if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
+                               
OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
+                       }
+ 

diff --git a/dev-lang/php/php-7.2.34.ebuild b/dev-lang/php/php-7.2.34-r1.ebuild
similarity index 99%
rename from dev-lang/php/php-7.2.34.ebuild
rename to dev-lang/php/php-7.2.34-r1.ebuild
index b7fe1520efb..a534bc594e5 100644
--- a/dev-lang/php/php-7.2.34.ebuild
+++ b/dev-lang/php/php-7.2.34-r1.ebuild
@@ -157,6 +157,7 @@ RESTRICT="!test? ( test )"
 PATCHES=(
        "${FILESDIR}/php-freetype-2.9.1.patch"
        "${FILESDIR}/php-7.2.13-intl-use-icu-namespace.patch"
+       "${FILESDIR}/php-7.2.34-use-after-free-bug76047.patch"
 )
 
 PHP_MV="$(ver_cut 1)"

Reply via email to