From 19b30032c9d7592e5b390de07d47de7abff90db1 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 15 Aug 2025 15:59:15 +0200 Subject: [PATCH] Fix uaf for nested finally with repeated return type check Fixes OSS-Fuzz #438780145 Closes GH-19488 --- NEWS | 2 ++ Zend/tests/oss_fuzz_438780145.phpt | 27 +++++++++++++++++++++++++++ Zend/zend_vm_def.h | 4 ++++ Zend/zend_vm_execute.h | 4 ++++ 4 files changed, 37 insertions(+) create mode 100644 Zend/tests/oss_fuzz_438780145.phpt diff --git a/NEWS b/NEWS index 19f900235d8..39f1d4e7db3 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,8 @@ PHP NEWS . Fixed bug GH-20766 (Use-after-free in FE_FREE with GC interaction). (Bob) . Fix OSS-Fuzz #471486164 (Broken by-ref assignment to uninitialized hooked backing value). (ilutov) + . Fix OSS-Fuzz #438780145 (Nested finally with repeated return type check may + uaf). (ilutov) - Date: . Update timelib to 2022.16. (Derick) diff --git a/Zend/tests/oss_fuzz_438780145.phpt b/Zend/tests/oss_fuzz_438780145.phpt new file mode 100644 index 00000000000..4c6936a69a0 --- /dev/null +++ b/Zend/tests/oss_fuzz_438780145.phpt @@ -0,0 +1,27 @@ +--TEST-- +OSS-Fuzz #438780145: Nested finally with repeated return type check may uaf +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught TypeError: test(): Return value must be of type int, string returned in %s:%d +Stack trace: +#0 %s(%d): test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 1f06eab120d..3e1026ef60e 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8537,6 +8537,10 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY) zval *return_value = EX_VAR(EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2.var); zval_ptr_dtor(return_value); + /* Clear return value in case we hit both DISCARD_EXCEPTION and + * zend_dispatch_try_catch_finally_helper, which will free the return + * value again. See OSS-Fuzz #438780145. */ + ZVAL_NULL(return_value); } /* cleanup delayed exception */ diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index fdef3e3a1b7..46c04bdd6d2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3365,6 +3365,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DISCARD_EXCEPTION_SPEC_HANDLER zval *return_value = EX_VAR(EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2.var); zval_ptr_dtor(return_value); + /* Clear return value in case we hit both DISCARD_EXCEPTION and + * zend_dispatch_try_catch_finally_helper, which will free the return + * value again. See OSS-Fuzz #438780145. */ + ZVAL_NULL(return_value); } /* cleanup delayed exception */