Skip to content

Commit b5ab271

Browse files
TimWollailuuu1994
andcommitted
Fix SHM unsafety
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
1 parent f5fd079 commit b5ab271

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
#[Override]: Inheritance check of inherited trait method against interface
3+
--FILE--
4+
<?php
5+
6+
trait T1 {
7+
public abstract function test();
8+
}
9+
10+
trait T2 {
11+
public function test() {}
12+
}
13+
14+
class A {
15+
use T2;
16+
}
17+
18+
class B extends A {
19+
use T1;
20+
}
21+
22+
?>
23+
===DONE===
24+
--EXPECT--
25+
===DONE===

Zend/zend_inheritance.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,12 +1081,13 @@ static void perform_delayable_implementation_check(
10811081
/**
10821082
* @param check_only Set to false to throw compile errors on incompatible methods, or true to return INHERITANCE_ERROR.
10831083
* @param checked Whether the compatibility check has already succeeded in zend_can_early_bind().
1084+
* @param force_mutable Whether we know that child may be modified, i.e. doesn't live in shm.
10841085
*/
10851086
static zend_always_inline inheritance_status do_inheritance_check_on_method_ex(
10861087
zend_function *child, zend_class_entry *child_scope,
10871088
zend_function *parent, zend_class_entry *parent_scope,
10881089
zend_class_entry *ce, zval *child_zv,
1089-
bool check_visibility, bool check_only, bool checked) /* {{{ */
1090+
bool check_visibility, bool check_only, bool checked, bool force_mutable) /* {{{ */
10901091
{
10911092
uint32_t child_flags;
10921093
uint32_t parent_flags = parent->common.fn_flags;
@@ -1188,13 +1189,7 @@ static zend_always_inline inheritance_status do_inheritance_check_on_method_ex(
11881189
perform_delayable_implementation_check(ce, child, child_scope, parent, parent_scope);
11891190
}
11901191

1191-
if (
1192-
!check_only
1193-
&& (
1194-
child->common.scope == ce
1195-
|| (child->common.fn_flags & ZEND_ACC_TRAIT_CLONE)
1196-
)
1197-
) {
1192+
if (!check_only && (child->common.scope == ce || force_mutable)) {
11981193
child->common.fn_flags &= ~ZEND_ACC_OVERRIDE;
11991194
}
12001195

@@ -1207,7 +1202,7 @@ static zend_never_inline void do_inheritance_check_on_method(
12071202
zend_function *parent, zend_class_entry *parent_scope,
12081203
zend_class_entry *ce, zval *child_zv, bool check_visibility)
12091204
{
1210-
do_inheritance_check_on_method_ex(child, child_scope, parent, parent_scope, ce, child_zv, check_visibility, 0, 0);
1205+
do_inheritance_check_on_method_ex(child, child_scope, parent, parent_scope, ce, child_zv, check_visibility, 0, 0, /* force_mutable */ false);
12111206
}
12121207

12131208
static zend_always_inline void do_inherit_method(zend_string *key, zend_function *parent, zend_class_entry *ce, bool is_interface, bool checked) /* {{{ */
@@ -1225,7 +1220,7 @@ static zend_always_inline void do_inherit_method(zend_string *key, zend_function
12251220
if (checked) {
12261221
do_inheritance_check_on_method_ex(
12271222
func, func->common.scope, parent, parent->common.scope, ce, child,
1228-
/* check_visibility */ 1, 0, checked);
1223+
/* check_visibility */ 1, 0, checked, /* force_mutable */ false);
12291224
} else {
12301225
do_inheritance_check_on_method(
12311226
func, func->common.scope, parent, parent->common.scope, ce, child,
@@ -2011,9 +2006,9 @@ static void zend_add_trait_method(zend_class_entry *ce, zend_string *name, zend_
20112006
if (check_inheritance) {
20122007
/* Inherited members are overridden by members inserted by traits.
20132008
* Check whether the trait method fulfills the inheritance requirements. */
2014-
do_inheritance_check_on_method(
2009+
do_inheritance_check_on_method_ex(
20152010
fn, fixup_trait_scope(fn, ce), existing_fn, fixup_trait_scope(existing_fn, ce),
2016-
ce, NULL, /* check_visibility */ 1);
2011+
ce, NULL, /* check_visibility */ 1, false, false, /* force_mutable */ true);
20172012
}
20182013
}
20192014
/* }}} */
@@ -3250,7 +3245,7 @@ static inheritance_status zend_can_early_bind(zend_class_entry *ce, zend_class_e
32503245
do_inheritance_check_on_method_ex(
32513246
child_func, child_func->common.scope,
32523247
parent_func, parent_func->common.scope,
3253-
ce, NULL, /* check_visibility */ 1, 1, 0);
3248+
ce, NULL, /* check_visibility */ 1, 1, 0, /* force_mutable */ false);
32543249
if (UNEXPECTED(status == INHERITANCE_WARNING)) {
32553250
overall_status = INHERITANCE_WARNING;
32563251
} else if (UNEXPECTED(status != INHERITANCE_SUCCESS)) {

0 commit comments

Comments
 (0)