Skip to content

Commit 0950a08

Browse files
committed
There may or may not be a readable ZEND_TRACE_OP_INFO()
Maybe I don't understand the code well enough, but I don't think it should happen. We had crashes there though, so that should probably should mitigate them. Signed-off-by: Bob Weinand <[email protected]>
1 parent 7b487bd commit 0950a08

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

zend_abstract_interface/jit_utils/jit_blacklist.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ typedef union _zend_op_trace_info {
8888

8989
#define ZEND_OP_TRACE_INFO(opline, offset) \
9090
((zend_op_trace_info*)(((char*)opline) + offset))
91+
92+
static int dd_probe_pipes[2];
9193
#endif
9294

9395
#define ZEND_FUNC_INFO(op_array) \
@@ -103,6 +105,9 @@ static void zai_jit_find_opcache_handle(void *ext) {
103105

104106
// opcache startup NULLs its handle. MINIT is executed before extension startup.
105107
void zai_jit_minit(void) {
108+
#if PHP_VERSION_ID < 80400
109+
pipe(dd_probe_pipes);
110+
#endif
106111
zend_llist_apply(&zend_extensions, zai_jit_find_opcache_handle);
107112
}
108113

@@ -188,7 +193,7 @@ void zai_jit_blacklist_function_inlining(zend_op_array *op_array) {
188193
if (zai_get_zend_func_rid(op_array) < 0) {
189194
return;
190195
}
191-
// now in PHP < 8.1, zend_func_info_rid is set
196+
// now in PHP < 8.1, zend_func_info_rid is set (on newer versions it's in zend_func_info.h)
192197

193198
zend_jit_op_array_trace_extension *jit_extension = (zend_jit_op_array_trace_extension *)ZEND_FUNC_INFO(op_array);
194199
if (!jit_extension) {
@@ -203,6 +208,14 @@ void zai_jit_blacklist_function_inlining(zend_op_array *op_array) {
203208

204209
size_t offset = jit_extension->offset;
205210

211+
// check whether the op_trace_info is actually readable or EFAULTing
212+
// we can't trust opcache too much here...
213+
char dummy_buf[sizeof(zend_op_trace_info)];
214+
if (write(dd_probe_pipes[1], ZEND_OP_TRACE_INFO(opline, offset), sizeof(zend_op_trace_info)) < 0) {
215+
return;
216+
}
217+
read(dd_probe_pipes[0], dummy_buf, sizeof(zend_op_trace_info));
218+
206219
if (!(ZEND_OP_TRACE_INFO(opline, offset)->trace_flags & ZEND_JIT_TRACE_BLACKLISTED)) {
207220
bool is_protected_memory = false;
208221
zend_string *protect_memory = zend_string_init(ZEND_STRL("opcache.protect_memory"), 0);

0 commit comments

Comments
 (0)