Gentoo Archives: gentoo-commits

From: Thomas Deutschmann <whissi@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: dev-lang/php/files/, dev-lang/php/
Date: Wed, 23 Dec 2020 00:39:13
Message-Id: 1608683945.280c5e27b96f27eed2f3325576d74361abb36294.whissi@gentoo
1 commit: 280c5e27b96f27eed2f3325576d74361abb36294
2 Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
3 AuthorDate: Wed Dec 23 00:38:40 2020 +0000
4 Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
5 CommitDate: Wed Dec 23 00:39:05 2020 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=280c5e27
7
8 dev-lang/php: fix use-after-free when accessing already destructed backtrace arguments
9
10 Bug: https://bugs.gentoo.org/711140
11 Package-Manager: Portage-3.0.12, Repoman-3.0.2
12 Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
13
14 .../files/php-7.2.34-use-after-free-bug76047.patch | 174 +++++++++++++++++++++
15 .../{php-7.2.34.ebuild => php-7.2.34-r1.ebuild} | 1 +
16 2 files changed, 175 insertions(+)
17
18 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
19 new file mode 100644
20 index 00000000000..b3a864ee82a
21 --- /dev/null
22 +++ b/dev-lang/php/files/php-7.2.34-use-after-free-bug76047.patch
23 @@ -0,0 +1,174 @@
24 +Backport of https://git.php.net/?p=php-src.git;a=commit;h=ef1e4891b47949c8dc0f9482eef9454a0ecdfa1d
25 +
26 +--- a/Zend/tests/bug52361.phpt
27 ++++ b/Zend/tests/bug52361.phpt
28 +@@ -25,9 +25,8 @@ try {
29 + --EXPECTF--
30 + 1. Exception: aaa in %sbug52361.php:5
31 + Stack trace:
32 +-#0 %sbug52361.php(13): aaa->__destruct()
33 +-#1 %sbug52361.php(16): bbb()
34 +-#2 {main}
35 ++#0 %sbug52361.php(16): aaa->__destruct()
36 ++#1 {main}
37 + 2. Exception: bbb in %sbug52361.php:13
38 + Stack trace:
39 + #0 %sbug52361.php(16): bbb()
40 +--- /dev/null
41 ++++ b/Zend/tests/bug76047.phpt
42 +@@ -0,0 +1,68 @@
43 ++--TEST--
44 ++Bug #76047: Use-after-free when accessing already destructed backtrace arguments
45 ++--FILE--
46 ++<?php
47 ++
48 ++class Vuln {
49 ++ public $a;
50 ++ public function __destruct() {
51 ++ unset($this->a);
52 ++ $backtrace = (new Exception)->getTrace();
53 ++ var_dump($backtrace);
54 ++ }
55 ++}
56 ++
57 ++function test($arg) {
58 ++ $arg = str_shuffle(str_repeat('A', 79));
59 ++ $vuln = new Vuln();
60 ++ $vuln->a = $arg;
61 ++}
62 ++
63 ++function test2($arg) {
64 ++ $$arg = 1; // Trigger symbol table
65 ++ $arg = str_shuffle(str_repeat('A', 79));
66 ++ $vuln = new Vuln();
67 ++ $vuln->a = $arg;
68 ++}
69 ++
70 ++test('x');
71 ++test2('x');
72 ++
73 ++?>
74 ++--EXPECTF--
75 ++array(1) {
76 ++ [0]=>
77 ++ array(6) {
78 ++ ["file"]=>
79 ++ string(%d) "%s"
80 ++ ["line"]=>
81 ++ int(%d)
82 ++ ["function"]=>
83 ++ string(10) "__destruct"
84 ++ ["class"]=>
85 ++ string(4) "Vuln"
86 ++ ["type"]=>
87 ++ string(2) "->"
88 ++ ["args"]=>
89 ++ array(0) {
90 ++ }
91 ++ }
92 ++}
93 ++array(1) {
94 ++ [0]=>
95 ++ array(6) {
96 ++ ["file"]=>
97 ++ string(%d) "%s"
98 ++ ["line"]=>
99 ++ int(%d)
100 ++ ["function"]=>
101 ++ string(10) "__destruct"
102 ++ ["class"]=>
103 ++ string(4) "Vuln"
104 ++ ["type"]=>
105 ++ string(2) "->"
106 ++ ["args"]=>
107 ++ array(0) {
108 ++ }
109 ++ }
110 ++}
111 +--- a/Zend/zend_vm_def.h
112 ++++ b/Zend/zend_vm_def.h
113 +@@ -2366,9 +2366,9 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
114 + uint32_t call_info = EX_CALL_INFO();
115 +
116 + if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
117 ++ EG(current_execute_data) = EX(prev_execute_data);
118 + i_free_compiled_variables(execute_data);
119 +
120 +- EG(current_execute_data) = EX(prev_execute_data);
121 + if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
122 + zend_object *object = Z_OBJ(execute_data->This);
123 + #if 0
124 +@@ -2394,12 +2394,12 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
125 + LOAD_NEXT_OPLINE();
126 + ZEND_VM_LEAVE();
127 + } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
128 ++ EG(current_execute_data) = EX(prev_execute_data);
129 + i_free_compiled_variables(execute_data);
130 +
131 + if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
132 + zend_clean_and_cache_symbol_table(EX(symbol_table));
133 + }
134 +- EG(current_execute_data) = EX(prev_execute_data);
135 +
136 + /* Free extra args before releasing the closure,
137 + * as that may free the op_array. */
138 +@@ -2449,6 +2449,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
139 + ZEND_VM_LEAVE();
140 + } else {
141 + if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
142 ++ EG(current_execute_data) = EX(prev_execute_data);
143 + i_free_compiled_variables(execute_data);
144 + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
145 + if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
146 +@@ -2456,7 +2457,6 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
147 + }
148 + zend_vm_stack_free_extra_args_ex(call_info, execute_data);
149 + }
150 +- EG(current_execute_data) = EX(prev_execute_data);
151 + if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
152 + OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
153 + }
154 +--- a/Zend/zend_vm_execute.h
155 ++++ b/Zend/zend_vm_execute.h
156 +@@ -434,9 +434,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_
157 + uint32_t call_info = EX_CALL_INFO();
158 +
159 + if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
160 ++ EG(current_execute_data) = EX(prev_execute_data);
161 + i_free_compiled_variables(execute_data);
162 +
163 +- EG(current_execute_data) = EX(prev_execute_data);
164 + if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
165 + zend_object *object = Z_OBJ(execute_data->This);
166 + #if 0
167 +@@ -462,12 +462,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_
168 + LOAD_NEXT_OPLINE();
169 + ZEND_VM_LEAVE();
170 + } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
171 ++ EG(current_execute_data) = EX(prev_execute_data);
172 + i_free_compiled_variables(execute_data);
173 +
174 + if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
175 + zend_clean_and_cache_symbol_table(EX(symbol_table));
176 + }
177 +- EG(current_execute_data) = EX(prev_execute_data);
178 +
179 + /* Free extra args before releasing the closure,
180 + * as that may free the op_array. */
181 +@@ -517,6 +517,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_
182 + ZEND_VM_LEAVE();
183 + } else {
184 + if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
185 ++ EG(current_execute_data) = EX(prev_execute_data);
186 + i_free_compiled_variables(execute_data);
187 + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
188 + if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
189 +@@ -524,7 +525,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_
190 + }
191 + zend_vm_stack_free_extra_args_ex(call_info, execute_data);
192 + }
193 +- EG(current_execute_data) = EX(prev_execute_data);
194 + if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
195 + OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
196 + }
197 +
198
199 diff --git a/dev-lang/php/php-7.2.34.ebuild b/dev-lang/php/php-7.2.34-r1.ebuild
200 similarity index 99%
201 rename from dev-lang/php/php-7.2.34.ebuild
202 rename to dev-lang/php/php-7.2.34-r1.ebuild
203 index b7fe1520efb..a534bc594e5 100644
204 --- a/dev-lang/php/php-7.2.34.ebuild
205 +++ b/dev-lang/php/php-7.2.34-r1.ebuild
206 @@ -157,6 +157,7 @@ RESTRICT="!test? ( test )"
207 PATCHES=(
208 "${FILESDIR}/php-freetype-2.9.1.patch"
209 "${FILESDIR}/php-7.2.13-intl-use-icu-namespace.patch"
210 + "${FILESDIR}/php-7.2.34-use-after-free-bug76047.patch"
211 )
212
213 PHP_MV="$(ver_cut 1)"