From 04b35a44ce335a1578a41cc60a888dab6a5a9508 Mon Sep 17 00:00:00 2001 From: sji Date: Sat, 28 Oct 2023 21:59:06 +0900 Subject: [PATCH 1/4] Fix segfault caused by weak references to FFI objects (#12488) Thank you! --- ext/ffi/ffi.c | 13 ++++++++++ ext/ffi/tests/weak_reference_001.phpt | 17 +++++++++++++ ext/ffi/tests/weak_reference_002.phpt | 36 +++++++++++++++++++++++++++ ext/ffi/tests/weak_reference_003.phpt | 17 +++++++++++++ ext/ffi/tests/weak_reference_004.phpt | 36 +++++++++++++++++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 ext/ffi/tests/weak_reference_001.phpt create mode 100644 ext/ffi/tests/weak_reference_002.phpt create mode 100644 ext/ffi/tests/weak_reference_003.phpt create mode 100644 ext/ffi/tests/weak_reference_004.phpt diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index efb4524c76b..a2779b65b12 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -24,6 +24,7 @@ #include "php_scandir.h" #include "zend_exceptions.h" #include "zend_closures.h" +#include "zend_weakrefs.h" #include "main/SAPI.h" #include "ffi_arginfo.h" @@ -2143,6 +2144,10 @@ static void zend_ffi_ctype_free_obj(zend_object *object) /* {{{ */ zend_ffi_ctype *ctype = (zend_ffi_ctype*)object; zend_ffi_type_dtor(ctype->type); + + if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) { + zend_weakrefs_notify(object); + } } /* }}} */ @@ -2369,6 +2374,10 @@ static void zend_ffi_free_obj(zend_object *object) /* {{{ */ zend_hash_destroy(ffi->tags); efree(ffi->tags); } + + if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) { + zend_weakrefs_notify(object); + } } /* }}} */ @@ -2377,6 +2386,10 @@ static void zend_ffi_cdata_free_obj(zend_object *object) /* {{{ */ zend_ffi_cdata *cdata = (zend_ffi_cdata*)object; zend_ffi_cdata_dtor(cdata); + + if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) { + zend_weakrefs_notify(object); + } } /* }}} */ diff --git a/ext/ffi/tests/weak_reference_001.phpt b/ext/ffi/tests/weak_reference_001.phpt new file mode 100644 index 00000000000..56f0be981f6 --- /dev/null +++ b/ext/ffi/tests/weak_reference_001.phpt @@ -0,0 +1,17 @@ +--TEST-- +Weak reference to \FFI +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +get() === $ffi); +unset($ffi); +var_dump($ref->get() === null); +?> +--EXPECTF-- +bool(true) +bool(true) diff --git a/ext/ffi/tests/weak_reference_002.phpt b/ext/ffi/tests/weak_reference_002.phpt new file mode 100644 index 00000000000..5c36cfa7034 --- /dev/null +++ b/ext/ffi/tests/weak_reference_002.phpt @@ -0,0 +1,36 @@ +--TEST-- +Weak reference to \FFI\CData +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +get() === $cdata_value); +var_dump($ref_array->get() === $cdata_array); +var_dump($ref_free->get() === $cdata_free); + +unset($cdata_value); +unset($cdata_array); +unset($cdata_free); + +var_dump($ref_value->get() === null); +var_dump($ref_array->get() === null); +var_dump($ref_free->get() === null); +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/ffi/tests/weak_reference_003.phpt b/ext/ffi/tests/weak_reference_003.phpt new file mode 100644 index 00000000000..15b9397a685 --- /dev/null +++ b/ext/ffi/tests/weak_reference_003.phpt @@ -0,0 +1,17 @@ +--TEST-- +Weak reference to \FFI\CType +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +get() === $ctype); +unset($ctype); +var_dump($ref->get() === null); +?> +--EXPECTF-- +bool(true) +bool(true) diff --git a/ext/ffi/tests/weak_reference_004.phpt b/ext/ffi/tests/weak_reference_004.phpt new file mode 100644 index 00000000000..500776fa218 --- /dev/null +++ b/ext/ffi/tests/weak_reference_004.phpt @@ -0,0 +1,36 @@ +--TEST-- +Using FFI Types for keys of a WeakMap +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- + +--EXPECTF-- +bool(true) +bool(true) From bbfadd32e8c50259c7cf25615e67f82c12f57b6d Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Sat, 28 Oct 2023 15:02:20 +0200 Subject: [PATCH 2/4] [ci skip] NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 68b54c0619f..ee42cf7c4eb 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ PHP NEWS - Core: . Fixed bug GH-12468 (Double-free of doc_comment when overriding static property via trait). (ilutov) + . Fixed segfault caused by weak references to FFI objects. (sj-i) - DOM: . Fix registerNodeClass with abstract class crashing. (nielsdos) From ae9118a7e431e96d2bc907d77a9e33d99acf8885 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Sat, 28 Oct 2023 15:04:13 +0200 Subject: [PATCH 3/4] [ci skip] NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index ee76548d210..39cac470368 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ PHP NEWS needle). (SakiTakamachi) . Fixed bug GH-12468 (Double-free of doc_comment when overriding static property via trait). (ilutov) + . Fixed segfault caused by weak references to FFI objects. (sj-i) - DOM: . Fix registerNodeClass with abstract class crashing. (nielsdos) From 79e1830dddeb7cf6cc4b31045d7cb718bcc88a3e Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Sat, 28 Oct 2023 15:06:15 +0200 Subject: [PATCH 4/4] [ci skip] NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 96dd60f1f8b..b06d88ce000 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ PHP NEWS needle). (SakiTakamachi) . Fixed bug GH-12468 (Double-free of doc_comment when overriding static property via trait). (ilutov) + . Fixed segfault caused by weak references to FFI objects. (sj-i) - DOM: . Fix registerNodeClass with abstract class crashing. (nielsdos)