From 7cba5e9bbd377f2633c734fa649bea8df93da1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= Date: Thu, 30 Jul 2026 09:41:34 +0200 Subject: [PATCH 1/2] fix: UB when upcasting yoga sentinel value --- packages/react-native/ReactCommon/yoga/yoga/YGNode.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGNode.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGNode.cpp index 7e66845fc173..7b9a5e4a7341 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGNode.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGNode.cpp @@ -279,11 +279,17 @@ size_t YGNodeGetChildCount(const YGNodeConstRef node) { } YGNodeRef YGNodeGetOwner(const YGNodeRef node) { - return resolveRef(node)->getOwner(); + // The owner is returned verbatim as an opaque handle. It may hold a + // non-dereferenceable sentinel value, so it must not undergo a + // derived-to-base conversion that asserts pointer alignment/validity. + return reinterpret_cast(resolveRef(node)->getOwner()); } YGNodeRef YGNodeGetParent(const YGNodeRef node) { - return resolveRef(node)->getOwner(); + // The owner is returned verbatim as an opaque handle. It may hold a + // non-dereferenceable sentinel value, so it must not undergo a + // derived-to-base conversion that asserts pointer alignment/validity. + return reinterpret_cast(resolveRef(node)->getOwner()); } void YGNodeSetConfig(YGNodeRef node, YGConfigRef config) { From 4be848a6f73750498fb1fa2ed353b730ae5c5c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= Date: Thu, 30 Jul 2026 11:17:55 +0200 Subject: [PATCH 2/2] refactor: use 8 byte alignment --- .../components/view/YogaLayoutableShadowNode.cpp | 2 +- packages/react-native/ReactCommon/yoga/yoga/YGNode.cpp | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp index ebe98db8eb4d..eaf72fdb2cce 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -338,7 +338,7 @@ void YogaLayoutableShadowNode::updateYogaChildrenOwnersIfNeeded() { // initialised function-local static. // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast) static auto* const kDetachedYogaNodeOwnerSentinel = - reinterpret_cast(0xBADC0FFEE0DDF00DULL); + reinterpret_cast(0xBADC0FFEE0DDF000ULL); // NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast) for (auto& childYogaNode : yogaNode_.getChildren()) { if (YGNodeGetOwner(childYogaNode) == &yogaNode_) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGNode.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGNode.cpp index 7b9a5e4a7341..7e66845fc173 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGNode.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGNode.cpp @@ -279,17 +279,11 @@ size_t YGNodeGetChildCount(const YGNodeConstRef node) { } YGNodeRef YGNodeGetOwner(const YGNodeRef node) { - // The owner is returned verbatim as an opaque handle. It may hold a - // non-dereferenceable sentinel value, so it must not undergo a - // derived-to-base conversion that asserts pointer alignment/validity. - return reinterpret_cast(resolveRef(node)->getOwner()); + return resolveRef(node)->getOwner(); } YGNodeRef YGNodeGetParent(const YGNodeRef node) { - // The owner is returned verbatim as an opaque handle. It may hold a - // non-dereferenceable sentinel value, so it must not undergo a - // derived-to-base conversion that asserts pointer alignment/validity. - return reinterpret_cast(resolveRef(node)->getOwner()); + return resolveRef(node)->getOwner(); } void YGNodeSetConfig(YGNodeRef node, YGConfigRef config) {