From df5ffe037ecd2abeaf9677def6e1d2db4d0d7898 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sat, 19 Sep 2026 23:46:40 -0400 Subject: [PATCH] P5f fr: guard registry frontend surfaces before arm selection --- MobileGL/MG_Backend/DirectGLES/Managers.h | 24 +++++++++++++++++-- MobileGL/MG_Test/Wire/RemoteClientTest.cpp | 28 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.h b/MobileGL/MG_Backend/DirectGLES/Managers.h index 60ce40db..0d98cc72 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.h +++ b/MobileGL/MG_Backend/DirectGLES/Managers.h @@ -329,6 +329,11 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif BackendPtr& GetOrCreate(const StatePtr& stateObj) { +#if MOBILEGL_BUILD_DISAGGREGATED + // Check before arm selection: disabling slot tables must not expose the + // legacy raw-pointer registry on a transport apply thread. + MG_Pipe::MGPipeRefuseFrontendKeyedRegistryFromApplyThread("Registry.GetOrCreate(StatePtr)"); +#endif MOBILEGL_ASSERT(stateObj != nullptr, "State object must not be null"); #if MOBILEGL_PIPE_PUSH @@ -389,6 +394,11 @@ namespace MobileGL::MG_Backend::DirectGLES { // need the twin across another registry call must copy the BackendPtr out (or keep only // the pointee, which is heap-allocated and never moves). BackendPtr* Find(StateObject* stateObj) { +#if MOBILEGL_BUILD_DISAGGREGATED + // Check before arm selection: disabling slot tables must not expose the + // legacy raw-pointer registry on a transport apply thread. + MG_Pipe::MGPipeRefuseFrontendKeyedRegistryFromApplyThread("Registry.Find(StateObject*)"); +#endif #if MOBILEGL_PIPE_PUSH if (EsprytSlotTablesEnabled()) { return m_slotTable.Find(stateObj); @@ -409,8 +419,18 @@ namespace MobileGL::MG_Backend::DirectGLES { return const_cast(this)->Find(stateObj); } - iterator begin() { return m_entries.begin(); } - const_iterator begin() const { return m_entries.begin(); } + iterator begin() { +#if MOBILEGL_BUILD_DISAGGREGATED + MG_Pipe::MGPipeRefuseFrontendKeyedRegistryFromApplyThread("Registry.begin"); +#endif + return m_entries.begin(); + } + const_iterator begin() const { +#if MOBILEGL_BUILD_DISAGGREGATED + MG_Pipe::MGPipeRefuseFrontendKeyedRegistryFromApplyThread("Registry.begin"); +#endif + return m_entries.begin(); + } iterator end() { return m_entries.end(); } const_iterator end() const { return m_entries.end(); } diff --git a/MobileGL/MG_Test/Wire/RemoteClientTest.cpp b/MobileGL/MG_Test/Wire/RemoteClientTest.cpp index 0e5dbf34..ad0028c0 100644 --- a/MobileGL/MG_Test/Wire/RemoteClientTest.cpp +++ b/MobileGL/MG_Test/Wire/RemoteClientTest.cpp @@ -2004,6 +2004,34 @@ TEST(RemoteGuards, BarrieredFrontendRegistryMembersRefuseBothLegacyScopes) { } } +TEST(RemoteGuards, LegacyRegistryWrapperCannotExposeFrontendKeysOnApply) { + using Registry = MG_Backend::DirectGLES::StateBackendObjectRegistry< + MG_State::GLState::TextureObject2D, FakeTwin, MGPipeKind::Texture>; + struct Probe { Registry* registry; SharedPtr* texture; int operation; }; + for (int operation = 0; operation != 3; ++operation) { + const auto child = RunInChild([operation] { + StartControlSession(); + auto texture = MakeShared(48); + Registry registry; + Probe probe{®istry, &texture, operation}; + Srv::ServerLoopInstance().RunProbeOnApplyThreadForTesting(+[](void* self) -> MobileGLResult { + auto& probe = *static_cast(self); + MG_Pipe::MGPipeApplierSetCurrentRecordBarriered(true); + const MG_Pipe::MGPipeFrontendKeyedRegistryScope scope; + switch (probe.operation) { + case 0: probe.registry->Find(probe.texture->get()); break; + case 1: probe.registry->GetOrCreate(*probe.texture); break; + case 2: (void)probe.registry->begin(); break; + } + return MOBILEGL_OK; + }, &probe); + ClientSessionInstance().Stop(); + }); + ExpectNamedAbort(child, "Fatal{RoleViolation, \"MGPipeSlots\"}"); + EXPECT_NE(child.Log.find("BackendSlotTable::Registry."), std::string::npos); + } +} + TEST(RemoteGuards, HandleRegistryMembersWorkOnBarrieredAndUnbarrieredApply) { const auto child = RunInChild([] { StartControlSession();