Skip to content

Commit

Permalink
Merge branch 'PHP-8.4'
Browse files Browse the repository at this point in the history
* PHP-8.4:
  Fix GH-17257: UBSAN warning in ext/opcache/jit/zend_jit_vm_helpers.c
  Fix GH-17223: Memory leak in libxml encoding handling
  • Loading branch information
nielsdos committed Dec 26, 2024
2 parents b4c5f4e + f4fb77e commit 466c8b0
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 7 deletions.
12 changes: 12 additions & 0 deletions ext/dom/tests/gh17223.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
GH-17223 (Memory leak in libxml encoding handling)
--EXTENSIONS--
dom
--FILE--
<?php
$doc = new DOMDocument("1.0", "Shift-JIS");
@$doc->save("%00");
echo "Done\n";
?>
--EXPECT--
Done
11 changes: 8 additions & 3 deletions ext/libxml/libxml.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,11 +562,11 @@ php_libxml_output_buffer_create_filename(const char *URI,
char *unescaped = NULL;

if (URI == NULL)
return(NULL);
goto err;

if (strstr(URI, "%00")) {
php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes");
return NULL;
goto err;
}

puri = xmlParseURI(URI);
Expand All @@ -587,7 +587,7 @@ php_libxml_output_buffer_create_filename(const char *URI,
}

if (context == NULL) {
return(NULL);
goto err;
}

/* Allocate the Output buffer front-end. */
Expand All @@ -599,6 +599,11 @@ php_libxml_output_buffer_create_filename(const char *URI,
}

return(ret);

err:
/* Similarly to __xmlOutputBufferCreateFilename we should also close the encoder on failure. */
xmlCharEncCloseFunc(encoder);
return NULL;
}

static void php_libxml_free_error(void *ptr)
Expand Down
1 change: 1 addition & 0 deletions ext/opcache/jit/zend_jit_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_func_counter_helper(ZEND_OPCODE_H
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_HANDLER_ARGS);

void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D);
void ZEND_FASTCALL zend_jit_copy_extra_args_helper_no_skip_recv(EXECUTE_DATA_D);
bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D);
void ZEND_FASTCALL zend_jit_undefined_long_key(EXECUTE_DATA_D);
void ZEND_FASTCALL zend_jit_undefined_long_key_ex(zend_long key EXECUTE_DATA_DC);
Expand Down
9 changes: 7 additions & 2 deletions ext/opcache/jit/zend_jit_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -3053,6 +3053,7 @@ static void zend_jit_setup_disasm(void)
REGISTER_HELPER(zend_jit_undefined_long_key_ex);
REGISTER_HELPER(zend_jit_undefined_string_key);
REGISTER_HELPER(zend_jit_copy_extra_args_helper);
REGISTER_HELPER(zend_jit_copy_extra_args_helper_no_skip_recv);
REGISTER_HELPER(zend_jit_vm_stack_free_args_helper);
REGISTER_HELPER(zend_free_extra_named_params);
REGISTER_HELPER(zend_jit_free_call_frame);
Expand Down Expand Up @@ -10292,6 +10293,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
}
}
} else {
ir_ref helper;
if (!trace || (trace->op == ZEND_JIT_TRACE_END
&& trace->stop >= ZEND_JIT_TRACE_STOP_INTERPRETER)) {
ir_ref ip;
Expand All @@ -10305,11 +10307,14 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
ip = ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes)));
}
jit_LOAD_IP(jit, ip);
helper = ir_CONST_FC_FUNC(zend_jit_copy_extra_args_helper);
} else {
helper = ir_CONST_FC_FUNC(zend_jit_copy_extra_args_helper_no_skip_recv);
}
if (GCC_GLOBAL_REGS) {
ir_CALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_copy_extra_args_helper));
ir_CALL(IR_VOID, helper);
} else {
ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_copy_extra_args_helper), jit_FP(jit));
ir_CALL_1(IR_VOID, helper, jit_FP(jit));
}
}
} else {
Expand Down
14 changes: 12 additions & 2 deletions ext/opcache/jit/zend_jit_vm_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_func_helper(EXECUTE_DATA_D)
}
}

void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D)
static void ZEND_FASTCALL zend_jit_copy_extra_args_helper_ex(bool skip_recv EXECUTE_DATA_DC)
{
zend_op_array *op_array = &EX(func)->op_array;

Expand All @@ -130,7 +130,7 @@ void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D)
zval *end, *src, *dst;
uint32_t type_flags = 0;

if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
if (skip_recv && EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
#ifdef HAVE_GCC_GLOBAL_REGS
opline += first_extra_arg;
Expand Down Expand Up @@ -166,6 +166,16 @@ void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D)
}
}

void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D)
{
zend_jit_copy_extra_args_helper_ex(true EXECUTE_DATA_CC);
}

void ZEND_FASTCALL zend_jit_copy_extra_args_helper_no_skip_recv(EXECUTE_DATA_D)
{
zend_jit_copy_extra_args_helper_ex(false EXECUTE_DATA_CC);
}

bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D)
{
zend_execute_data *call = (zend_execute_data *) opline;
Expand Down
25 changes: 25 additions & 0 deletions ext/opcache/tests/jit/gh17257.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
--TEST--
GH-17257 (SEGV ext/opcache/jit/zend_jit_vm_helpers.c)
--EXTENSIONS--
opcache
--INI--
opcache.jit_buffer_size=32M
opcache.jit=1254
opcache.jit_hot_func=1
--FILE--
<?php
function get_const() {
}
function test() {
call_user_func('get_const', 1); // need an extra arg to trigger the issue
}
function main(){
for ($i = 0; $i < 10; $i++) {
test();
}
echo "Done\n";
}
main();
?>
--EXPECT--
Done

0 comments on commit 466c8b0

Please sign in to comment.