diff --git a/Zend/tests/oss-fuzz-403816122.phpt b/Zend/tests/oss-fuzz-403816122.phpt
new file mode 100644
index 000000000000..b9d9400609fc
--- /dev/null
+++ b/Zend/tests/oss-fuzz-403816122.phpt
@@ -0,0 +1,22 @@
+--TEST--
+OSS-Fuzz #403816122: Segfault when initializing default properties of child prop with added hooks
+--FILE--
+<?php
+
+const X = 'x';
+
+class P {
+    public $prop;
+}
+
+class C extends P {
+    public $prop = X {
+        get => 'y';
+    }
+}
+
+var_dump((new C)->prop);
+
+?>
+--EXPECT--
+string(1) "y"
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 1021a6f7bd50..5aac3c1f7d77 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -1613,8 +1613,12 @@ ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type) /
 		/* Use the default properties table to also update initializers of private properties
 		 * that have been shadowed in a child class. */
 		for (uint32_t i = 0; i < class_type->default_properties_count; i++) {
-			val = &default_properties_table[i];
 			prop_info = class_type->properties_info_table[i];
+			if (!prop_info) {
+				continue;
+			}
+
+			val = &default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
 			if (Z_TYPE_P(val) == IS_CONSTANT_AST
 					&& UNEXPECTED(update_property(val, prop_info) != SUCCESS)) {
 				return FAILURE;
diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c
index 41ba3e1cd288..d1b950160e1c 100644
--- a/Zend/zend_lazy_objects.c
+++ b/Zend/zend_lazy_objects.c
@@ -268,14 +268,17 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj,
 
 		obj = zend_objects_new(reflection_ce);
 
-		for (int i = 0; i < obj->ce->default_properties_count; i++) {
+		/* Iterate in reverse to avoid overriding Z_PROP_FLAG_P() of child props with added hooks (GH-17870). */
+		for (int i = obj->ce->default_properties_count - 1; i >= 0; i--) {
 			zval *p = &obj->properties_table[i];
 			ZVAL_UNDEF(p);
-			if (EXPECTED(obj->ce->properties_info_table[i])) {
+			Z_PROP_FLAG_P(p) = 0;
+
+			zend_property_info *prop_info = obj->ce->properties_info_table[i];
+			if (prop_info) {
+				zval *p = &obj->properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
 				Z_PROP_FLAG_P(p) = IS_PROP_UNINIT | IS_PROP_LAZY;
 				lazy_properties_count++;
-			} else {
-				Z_PROP_FLAG_P(p) = 0;
 			}
 		}
 	} else {
@@ -326,7 +329,7 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj,
 		for (int i = 0; i < reflection_ce->default_properties_count; i++) {
 			zend_property_info *prop_info = obj->ce->properties_info_table[i];
 			if (EXPECTED(prop_info)) {
-				zval *p = &obj->properties_table[i];
+				zval *p = &obj->properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
 				if (Z_TYPE_P(p) != IS_UNDEF) {
 					if ((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(p) & IS_PROP_REINITABLE)
 							/* TODO: test final property */
@@ -408,12 +411,16 @@ static void zend_lazy_object_revert_init(zend_object *obj, zval *properties_tabl
 		zval *properties_table = obj->properties_table;
 
 		for (int i = 0; i < ce->default_properties_count; i++) {
-			zval *p = &properties_table[i];
+			zend_property_info *prop_info = ce->properties_info_table[i];
+			if (!prop_info) {
+				continue;
+			}
+
+			zval *p = &properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
 			zend_object_dtor_property(obj, p);
-			ZVAL_COPY_VALUE_PROP(p, &properties_table_snapshot[i]);
+			ZVAL_COPY_VALUE_PROP(p, &properties_table_snapshot[OBJ_PROP_TO_NUM(prop_info->offset)]);
 
-			zend_property_info *prop_info = ce->properties_info_table[i];
-			if (Z_ISREF_P(p) && prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
+			if (Z_ISREF_P(p) && ZEND_TYPE_IS_SET(prop_info->type)) {
 				ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(p), prop_info);
 			}
 		}
@@ -526,10 +533,12 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj)
 	obj->properties = NULL;
 
 	for (int i = 0; i < Z_OBJ(retval)->ce->default_properties_count; i++) {
-		if (EXPECTED(Z_OBJ(retval)->ce->properties_info_table[i])) {
-			zend_object_dtor_property(obj, &obj->properties_table[i]);
-			ZVAL_UNDEF(&obj->properties_table[i]);
-			Z_PROP_FLAG_P(&obj->properties_table[i]) = IS_PROP_UNINIT | IS_PROP_LAZY;
+		zend_property_info *prop_info = Z_OBJ(retval)->ce->properties_info_table[i];
+		if (EXPECTED(prop_info)) {
+			zval *prop = &obj->properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
+			zend_object_dtor_property(obj, prop);
+			ZVAL_UNDEF(prop);
+			Z_PROP_FLAG_P(prop) = IS_PROP_UNINIT | IS_PROP_LAZY;
 		}
 	}
 
@@ -722,13 +731,16 @@ zend_object *zend_lazy_object_clone(zend_object *old_obj)
 	zend_class_entry *ce = old_obj->ce;
 	zend_object *new_proxy = zend_objects_new(ce);
 
-	for (int i = 0; i < ce->default_properties_count; i++) {
+	/* Iterate in reverse to avoid overriding Z_PROP_FLAG_P() of child props with added hooks (GH-17870). */
+	for (int i = ce->default_properties_count - 1; i >= 0; i--) {
 		zval *p = &new_proxy->properties_table[i];
 		ZVAL_UNDEF(p);
-		if (EXPECTED(ce->properties_info_table[i])) {
+		Z_PROP_FLAG_P(p) = 0;
+
+		zend_property_info *prop_info = ce->properties_info_table[i];
+		if (prop_info) {
+			zval *p = &new_proxy->properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
 			Z_PROP_FLAG_P(p) = IS_PROP_UNINIT | IS_PROP_LAZY;
-		} else {
-			Z_PROP_FLAG_P(p) = 0;
 		}
 	}
 
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 6e53b987d676..59ed26339e9c 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -3815,9 +3815,13 @@ static bool preload_try_resolve_constants(zend_class_entry *ce)
 			bool resolved = true;
 
 			for (i = 0; i < ce->default_properties_count; i++) {
-				val = &ce->default_properties_table[i];
+				zend_property_info *prop = ce->properties_info_table[i];
+				if (!prop) {
+					continue;
+				}
+
+				val = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop->offset)];
 				if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
-					zend_property_info *prop = ce->properties_info_table[i];
 					if (UNEXPECTED(zval_update_constant_ex(val, prop->ce) != SUCCESS)) {
 						resolved = ok = false;
 					}