You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Move the dummy function of call_attribute_constructor onto the VM stack (#2446)
* Move the dummy function of call_attribute_constructor onto the VM stack
Signed-off-by: Bob Weinand <[email protected]>
* Add log line for mprotect failure
Signed-off-by: Bob Weinand <[email protected]>
---------
Signed-off-by: Bob Weinand <[email protected]>
// On PHP 8.0.0-8.0.16 and 8.1.0-8.1.2 call_attribute_constructor would stack allocate a dummy frame, which could have become inaccessible upon access.
152
+
// Thus, we implement the fix which was applied to PHP itself as well: we move the stack allocated data to the VM stack.
153
+
// See also https://github.com/php/php-src/commit/f7c3f6e7e25471da9cfb2ba082a77cc3c85bc6ed
// We need to hijack zend_call_known_function as that's what's being called by call_attribute_constructor, and call_attribute_constructor itself is not exported.
// 20 is the largest size of a trampoline we have to inject
217
+
if ((((uintptr_t)zend_call_known_function+20) &page_size) <20) {
218
+
page_size <<= 1; // if overlapping pages, use two
219
+
}
220
+
if (mprotect(page, page_size, PROT_READ | PROT_WRITE) !=0) { // Some architectures enforce W^X (either write _or_ execute, but not both).
221
+
LOG(Error, "Could not alter the memory protection for zend_call_known_function. Tracer execution continues, but may crash when encountering attributes.");
222
+
return; // Make absolutely sure we can write
223
+
}
224
+
225
+
#ifdef__aarch64__
226
+
// x13 is a scratch register
227
+
uint32_tabsolute_jump_instrs[] = {
228
+
0x1000006D, // adr x13, 12 (load address from memory after this)
229
+
0xF94001AD, // ldr x13, [x13]
230
+
0xD61F01A0, // br x13
231
+
};
232
+
// The magical 12 is sizeof(absolute_jump_instrs) and hardcoded in the assembly above.
0 commit comments