File tree Expand file tree Collapse file tree 2 files changed +49
-0
lines changed Expand file tree Collapse file tree 2 files changed +49
-0
lines changed Original file line number Diff line number Diff line change @@ -1313,6 +1313,12 @@ ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce
1313
1313
ZEND_MAP_PTR_INIT (func -> run_time_cache , (void * * )dummy );
1314
1314
func -> scope = fbc -> common .scope ;
1315
1315
/* reserve space for arguments, local and temporary variables */
1316
+ /* EG(trampoline) is reused from other places, like FFI (e.g. zend_ffi_cdata_get_closure()) where
1317
+ * it is used as an internal function. It may set fields that don't belong to common, thus
1318
+ * modifying zend_op_array specific data, most significantly last_var. We need to reset this
1319
+ * value so that it doesn't contain garbage when the engine allocates space for the next stack
1320
+ * frame. This didn't cause any issues until now due to "lucky" structure layout. */
1321
+ func -> last_var = 0 ;
1316
1322
func -> T = (fbc -> type == ZEND_USER_FUNCTION )? MAX (fbc -> op_array .last_var + fbc -> op_array .T , 2 ) : 2 ;
1317
1323
func -> filename = (fbc -> type == ZEND_USER_FUNCTION )? fbc -> op_array .filename : ZSTR_EMPTY_ALLOC ();
1318
1324
func -> line_start = (fbc -> type == ZEND_USER_FUNCTION )? fbc -> op_array .line_start : 0 ;
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ Memory corruption when mixing __callStatic() and FFI
3
+ --EXTENSIONS--
4
+ ffi
5
+ --SKIPIF--
6
+ <?php
7
+ try {
8
+ $ libc = FFI ::cdef ("int printf(const char *format, ...); " , "libc.so.6 " );
9
+ } catch (Throwable $ _ ) {
10
+ die ('skip libc.so.6 not available ' );
11
+ }
12
+ ?>
13
+ --INI--
14
+ ffi.enable=1
15
+ --FILE--
16
+ <?php
17
+ class Test
18
+ {
19
+ public static function __callStatic ($ name , $ args )
20
+ {
21
+ echo "$ name called \n" ;
22
+ }
23
+ }
24
+
25
+ $ header = '
26
+ typedef struct _IO_FILE FILE;
27
+ extern FILE *stdout;
28
+ int fprintf(FILE *, const char *, ...);
29
+ int fflush(FILE *);
30
+ ' ;
31
+ $ ffi = FFI ::cdef ($ header , 'libc.so.6 ' );
32
+
33
+ Test::foo ();
34
+ Test::bar ();
35
+ $ ffi ->fprintf ($ ffi ->stdout , "FFI \n" );
36
+ $ ffi ->fflush ($ ffi ->stdout );
37
+ Test::baz ();
38
+ ?>
39
+ --EXPECT--
40
+ foo called
41
+ bar called
42
+ FFI
43
+ baz called
You can’t perform that action at this time.
0 commit comments