Skip to content

Commit bc57c77

Browse files
committed
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: [ci skip] NEWS for GH-14626 Fix is_zend_ptr() for huge blocks (#14626)
2 parents e230610 + a9acc29 commit bc57c77

File tree

6 files changed

+78
-11
lines changed

6 files changed

+78
-11
lines changed

Zend/tests/gh14626.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
GH-14626: is_zend_ptr() may crash for non-zend ptrs when huge blocks exist
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
// Ensure there is at least one huge_block
9+
$str = str_repeat('a', 2*1024*1024);
10+
11+
// Check that is_zend_ptr() does not crash
12+
zend_test_is_zend_ptr(0);
13+
zend_test_is_zend_ptr(1<<30);
14+
15+
?>
16+
==DONE==
17+
--EXPECT--
18+
==DONE==

Zend/zend_alloc.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2469,17 +2469,15 @@ ZEND_API bool is_zend_ptr(const void *ptr)
24692469
} while (chunk != AG(mm_heap)->main_chunk);
24702470
}
24712471

2472-
if (AG(mm_heap)->huge_list) {
2473-
zend_mm_huge_list *block = AG(mm_heap)->huge_list;
2474-
2475-
do {
2476-
if (ptr >= (void*)block
2477-
&& ptr < (void*)((char*)block + block->size)) {
2478-
return 1;
2479-
}
2480-
block = block->next;
2481-
} while (block != AG(mm_heap)->huge_list);
2472+
zend_mm_huge_list *block = AG(mm_heap)->huge_list;
2473+
while (block) {
2474+
if (ptr >= (void*)block
2475+
&& ptr < (void*)((char*)block + block->size)) {
2476+
return 1;
2477+
}
2478+
block = block->next;
24822479
}
2480+
24832481
return 0;
24842482
}
24852483

ext/ffi/tests/gh14626.phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
GH-14626: FFI::free() may crash in is_zend_ptr() when at least one huge block exists and the ptr is non-zend
3+
--EXTENSIONS--
4+
ffi
5+
--SKIPIF--
6+
<?php
7+
if (substr(PHP_OS, 0, 3) == 'WIN') die("skip no malloc() on windows");
8+
?>
9+
--INI--
10+
ffi.enable=1
11+
--FILE--
12+
<?php
13+
14+
// Ensure there is at least one huge_block
15+
$str = str_repeat('a', 2*1024*1024);
16+
17+
$ffi = FFI::cdef(<<<C
18+
void *malloc(size_t size);
19+
C);
20+
21+
$ptr = $ffi->malloc(10);
22+
$addr = $ffi->cast("uintptr_t", $ffi->cast("char*", $ptr))->cdata;
23+
24+
$ptr = FFI::cdef()->cast("char*", $addr);
25+
26+
// Should not crash in is_zend_ptr()
27+
FFI::free($ptr);
28+
29+
?>
30+
==DONE==
31+
--EXPECT--
32+
==DONE==

ext/zend_test/test.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,17 @@ static ZEND_FUNCTION(zend_test_cast_fread)
782782
}
783783
}
784784

785+
static ZEND_FUNCTION(zend_test_is_zend_ptr)
786+
{
787+
zend_long addr;
788+
789+
ZEND_PARSE_PARAMETERS_START(1, 1)
790+
Z_PARAM_LONG(addr);
791+
ZEND_PARSE_PARAMETERS_END();
792+
793+
RETURN_BOOL(is_zend_ptr((void*)addr));
794+
}
795+
785796
static zend_object *zend_test_class_new(zend_class_entry *class_type)
786797
{
787798
zend_object *obj = zend_objects_new(class_type);

ext/zend_test/test.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ function zend_test_set_fmode(bool $binary): void {}
253253

254254
/** @param resource $stream */
255255
function zend_test_cast_fread($stream): void {}
256+
257+
function zend_test_is_zend_ptr(int $addr): bool {}
256258
}
257259

258260
namespace ZendTestNS {

ext/zend_test/test_arginfo.h

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)