Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 50ccea3

Browse files
committed
Merge branch 'PHP-8.1' into PHP-8.2
2 parents 73246ba + 1305ea2 commit 50ccea3

File tree

7 files changed

+158
-2
lines changed

7 files changed

+158
-2
lines changed

‎NEWS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ PHP NEWS
77
error handler). (ilutov)
88
. Fixed oss-fuzz #64209 (In-place modification of filename in
99
php_message_handler_for_zend). (ilutov)
10+
. Fixed bug GH-12758 / GH-12768 (Invalid opline in OOM handlers within
11+
ZEND_FUNC_GET_ARGS and ZEND_BIND_STATIC). (Florian Engelhardt)
1012

1113
- Date:
1214
. Fixed improbably integer overflow while parsing really large (or small)

‎Zend/zend_vm_def.h‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8851,6 +8851,8 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
88518851

88528852
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
88538853

8854+
SAVE_OPLINE();
8855+
88548856
ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
88558857
if (!ht) {
88568858
ht = zend_array_dup(EX(func)->op_array.static_variables);
@@ -8860,7 +8862,6 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
88608862

88618863
value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT)));
88628864

8863-
SAVE_OPLINE();
88648865
if (opline->extended_value & ZEND_BIND_REF) {
88658866
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
88668867
if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
@@ -9314,6 +9315,7 @@ ZEND_VM_HANDLER(172, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
93149315
}
93159316

93169317
if (result_size) {
9318+
SAVE_OPLINE();
93179319
uint32_t first_extra_arg = EX(func)->op_array.num_args;
93189320

93199321
ht = zend_new_array(result_size);

‎Zend/zend_vm_execute.h‎

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

‎ext/zend_test/php_test.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
5555
int register_passes;
5656
bool print_stderr_mshutdown;
5757
zend_long limit_copy_file_range;
58+
int observe_opline_in_zendmm;
59+
zend_mm_heap* zend_orig_heap;
60+
zend_mm_heap* zend_test_heap;
5861
zend_test_fiber *active_fiber;
5962
zend_long quantity_value;
6063
zend_string *str_test;

‎ext/zend_test/test.c‎

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,16 @@
3030
#include "zend_interfaces.h"
3131
#include "zend_weakrefs.h"
3232
#include "Zend/Optimizer/zend_optimizer.h"
33+
#include "Zend/zend_alloc.h"
3334
#include "test.h"
3435
#include "test_arginfo.h"
3536

37+
// `php.h` sets `NDEBUG` when not `PHP_DEBUG` which will make `assert()` from
38+
// assert.h a no-op. In order to have `assert()` working on NDEBUG builds, we
39+
// undefine `NDEBUG` and re-include assert.h
40+
#undef NDEBUG
41+
#include "assert.h"
42+
3643
#if defined(HAVE_LIBXML) && !defined(PHP_WIN32)
3744
# include <libxml/globals.h>
3845
# include <libxml/parser.h>
@@ -501,6 +508,68 @@ static ZEND_FUNCTION(zend_test_crash)
501508
php_printf("%s", invalid);
502509
}
503510

511+
static bool has_opline(zend_execute_data *execute_data)
512+
{
513+
return execute_data
514+
&& execute_data->func
515+
&& ZEND_USER_CODE(execute_data->func->type)
516+
&& execute_data->opline
517+
;
518+
}
519+
520+
void * zend_test_custom_malloc(size_t len)
521+
{
522+
if (has_opline(EG(current_execute_data))) {
523+
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
524+
}
525+
return _zend_mm_alloc(ZT_G(zend_orig_heap), len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
526+
}
527+
528+
void zend_test_custom_free(void *ptr)
529+
{
530+
if (has_opline(EG(current_execute_data))) {
531+
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
532+
}
533+
_zend_mm_free(ZT_G(zend_orig_heap), ptr ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
534+
}
535+
536+
void * zend_test_custom_realloc(void * ptr, size_t len)
537+
{
538+
if (has_opline(EG(current_execute_data))) {
539+
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
540+
}
541+
return _zend_mm_realloc(ZT_G(zend_orig_heap), ptr, len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
542+
}
543+
544+
static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)
545+
{
546+
if (new_value == NULL) {
547+
return FAILURE;
548+
}
549+
550+
int int_value = zend_ini_parse_bool(new_value);
551+
552+
if (int_value == 1) {
553+
// `zend_mm_heap` is a private struct, so we have not way to find the
554+
// actual size, but 4096 bytes should be enough
555+
ZT_G(zend_test_heap) = malloc(4096);
556+
memset(ZT_G(zend_test_heap), 0, 4096);
557+
zend_mm_set_custom_handlers(
558+
ZT_G(zend_test_heap),
559+
zend_test_custom_malloc,
560+
zend_test_custom_free,
561+
zend_test_custom_realloc
562+
);
563+
ZT_G(zend_orig_heap) = zend_mm_get_heap();
564+
zend_mm_set_heap(ZT_G(zend_test_heap));
565+
} else if (ZT_G(zend_test_heap)) {
566+
free(ZT_G(zend_test_heap));
567+
ZT_G(zend_test_heap) = NULL;
568+
zend_mm_set_heap(ZT_G(zend_orig_heap));
569+
}
570+
return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
571+
}
572+
504573
static ZEND_FUNCTION(zend_test_is_pcre_bundled)
505574
{
506575
ZEND_PARSE_PARAMETERS_NONE();
@@ -743,6 +812,7 @@ PHP_INI_BEGIN()
743812
STD_PHP_INI_ENTRY("zend_test.quantity_value", "0", PHP_INI_ALL, OnUpdateLong, quantity_value, zend_zend_test_globals, zend_test_globals)
744813
STD_PHP_INI_ENTRY("zend_test.str_test", "", PHP_INI_ALL, OnUpdateStr, str_test, zend_zend_test_globals, zend_test_globals)
745814
STD_PHP_INI_ENTRY("zend_test.not_empty_str_test", "val", PHP_INI_ALL, OnUpdateStrNotEmpty, not_empty_str_test, zend_zend_test_globals, zend_test_globals)
815+
STD_PHP_INI_BOOLEAN("zend_test.observe_opline_in_zendmm", "0", PHP_INI_ALL, OnUpdateZendTestObserveOplineInZendMM, observe_opline_in_zendmm, zend_zend_test_globals, zend_test_globals)
746816
PHP_INI_END()
747817

748818
void (*old_zend_execute_ex)(zend_execute_data *execute_data);
@@ -899,6 +969,13 @@ PHP_RSHUTDOWN_FUNCTION(zend_test)
899969
zend_weakrefs_hash_del(&ZT_G(global_weakmap), zend_weakref_key_to_object(obj_key));
900970
} ZEND_HASH_FOREACH_END();
901971
zend_hash_destroy(&ZT_G(global_weakmap));
972+
973+
if (ZT_G(zend_test_heap)) {
974+
free(ZT_G(zend_test_heap));
975+
ZT_G(zend_test_heap) = NULL;
976+
zend_mm_set_heap(ZT_G(zend_orig_heap));
977+
}
978+
902979
return SUCCESS;
903980
}
904981

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
possible segfault in `ZEND_BIND_STATIC`
3+
--DESCRIPTION--
4+
https://github.com/php/php-src/pull/12758
5+
--EXTENSIONS--
6+
zend_test
7+
--INI--
8+
zend_test.observe_opline_in_zendmm=1
9+
--FILE--
10+
<?php
11+
12+
function &ref() {
13+
static $a = 5;
14+
return $a;
15+
}
16+
17+
class Foo {
18+
public static int $i;
19+
public static string $s = "x";
20+
}
21+
22+
var_dump(Foo::$i = "1");
23+
var_dump(Foo::$s, Foo::$i);
24+
var_dump(ref());
25+
26+
echo 'Done.';
27+
?>
28+
--EXPECT--
29+
int(1)
30+
string(1) "x"
31+
int(1)
32+
int(5)
33+
Done.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
possible segfault in `ZEND_FUNC_GET_ARGS`
3+
--DESCRIPTION--
4+
--EXTENSIONS--
5+
zend_test
6+
--INI--
7+
zend_test.observe_opline_in_zendmm=1
8+
--FILE--
9+
<?php
10+
11+
function ref() {
12+
return func_get_args();
13+
}
14+
15+
class Foo {
16+
public static int $i;
17+
public static string $s = "x";
18+
}
19+
20+
var_dump(Foo::$i = "1");
21+
var_dump(Foo::$s, Foo::$i);
22+
var_dump(ref('string', 0));
23+
24+
echo 'Done.';
25+
?>
26+
--EXPECT--
27+
int(1)
28+
string(1) "x"
29+
int(1)
30+
array(2) {
31+
[0]=>
32+
string(6) "string"
33+
[1]=>
34+
int(0)
35+
}
36+
Done.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /