From 472ce8c554b6972ee1a8f17fdee13548c6655620 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 6 Nov 2024 20:12:10 +0100 Subject: [PATCH] Fix GH-16630: UAF in lexer with encoding translation and heredocs zend_save_lexical_state() can be nested multiple times, for example for the parser initialization and then in the heredoc lexing. The input should not be freed if we restore to the same filtered string. --- Zend/tests/gh16630.phpt | 19 +++++++++++++++++++ Zend/zend_language_scanner.l | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/gh16630.phpt diff --git a/Zend/tests/gh16630.phpt b/Zend/tests/gh16630.phpt new file mode 100644 index 0000000000000..62d6c9956a7eb --- /dev/null +++ b/Zend/tests/gh16630.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-16630 (UAF in lexer with encoding translation and heredocs) +--EXTENSIONS-- +mbstring +--INI-- +zend.multibyte=On +zend.script_encoding=ISO-8859-1 +internal_encoding=EUC-JP +--FILE-- + +--EXPECT-- +heredoc +text diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index c3b27cbfc321c..8b46700eba338 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -275,7 +275,7 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state) CG(zend_lineno) = lex_state->lineno; zend_restore_compiled_filename(lex_state->filename); - if (SCNG(script_filtered)) { + if (SCNG(script_filtered) && SCNG(script_filtered) != lex_state->script_filtered) { efree(SCNG(script_filtered)); SCNG(script_filtered) = NULL; }