Skip to content

Commit

Permalink
Merge branch 'PHP-8.3'
Browse files Browse the repository at this point in the history
* PHP-8.3:
  [ci skip] NEWS for GH-14626
  [ci skip] NEWS for GH-14626
  Fix is_zend_ptr() for huge blocks (#14626)
  • Loading branch information
arnaud-lb committed Jun 25, 2024
2 parents df6d85a + a5a75ae commit f7df238
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 11 deletions.
18 changes: 18 additions & 0 deletions Zend/tests/gh14626.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
GH-14626: is_zend_ptr() may crash for non-zend ptrs when huge blocks exist
--EXTENSIONS--
zend_test
--FILE--
<?php

// Ensure there is at least one huge_block
$str = str_repeat('a', 2*1024*1024);

// Check that is_zend_ptr() does not crash
zend_test_is_zend_ptr(0);
zend_test_is_zend_ptr(1<<30);

?>
==DONE==
--EXPECT--
==DONE==
18 changes: 8 additions & 10 deletions Zend/zend_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2654,17 +2654,15 @@ ZEND_API bool is_zend_ptr(const void *ptr)
} while (chunk != AG(mm_heap)->main_chunk);
}

if (AG(mm_heap)->huge_list) {
zend_mm_huge_list *block = AG(mm_heap)->huge_list;

do {
if (ptr >= (void*)block
&& ptr < (void*)((char*)block + block->size)) {
return 1;
}
block = block->next;
} while (block != AG(mm_heap)->huge_list);
zend_mm_huge_list *block = AG(mm_heap)->huge_list;
while (block) {
if (ptr >= (void*)block
&& ptr < (void*)((char*)block + block->size)) {
return 1;
}
block = block->next;
}

return 0;
}

Expand Down
32 changes: 32 additions & 0 deletions ext/ffi/tests/gh14626.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--TEST--
GH-14626: FFI::free() may crash in is_zend_ptr() when at least one huge block exists and the ptr is non-zend
--EXTENSIONS--
ffi
--SKIPIF--
<?php
if (substr(PHP_OS, 0, 3) == 'WIN') die("skip no malloc() on windows");
?>
--INI--
ffi.enable=1
--FILE--
<?php

// Ensure there is at least one huge_block
$str = str_repeat('a', 2*1024*1024);

$ffi = FFI::cdef(<<<C
void *malloc(size_t size);
C);

$ptr = $ffi->malloc(10);
$addr = $ffi->cast("uintptr_t", $ffi->cast("char*", $ptr))->cdata;

$ptr = FFI::cdef()->cast("char*", $addr);

// Should not crash in is_zend_ptr()
FFI::free($ptr);

?>
==DONE==
--EXPECT--
==DONE==
11 changes: 11 additions & 0 deletions ext/zend_test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,17 @@ static ZEND_FUNCTION(zend_test_cast_fread)
}
}

static ZEND_FUNCTION(zend_test_is_zend_ptr)
{
zend_long addr;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_LONG(addr);
ZEND_PARSE_PARAMETERS_END();

RETURN_BOOL(is_zend_ptr((void*)addr));
}

static zend_object *zend_test_class_new(zend_class_entry *class_type)
{
zend_object *obj = zend_objects_new(class_type);
Expand Down
2 changes: 2 additions & 0 deletions ext/zend_test/test.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ function zend_test_set_fmode(bool $binary): void {}

/** @param resource $stream */
function zend_test_cast_fread($stream): void {}

function zend_test_is_zend_ptr(int $addr): bool {}
}

namespace ZendTestNS {
Expand Down
8 changes: 7 additions & 1 deletion ext/zend_test/test_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f7df238

Please sign in to comment.