diff --git a/NEWS b/NEWS index c9bf1b5a73b..34b0c40f418 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,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 11cad0920fb..1efd1cb5aa6 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8624,6 +8624,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 2545ea7f872..a292bbbed4b 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3498,6 +3498,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DISCARD_EXCEP 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 */ @@ -59133,6 +59137,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DISCARD_EXCEPTION_ 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 */