From 7ce19da02b0e344cf599699c8ba6aec2d052703d Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sat, 19 Sep 2026 23:43:32 -0400 Subject: [PATCH] P5f fr: guard client allocator singleton including bookkeeping reads --- MobileGL/MG_Impl/Pipe/SlotAllocator.cpp | 6 ++++++ MobileGL/MG_Impl/Pipe/SlotAllocator.h | 4 ++-- MobileGL/MG_Test/Wire/RemoteClientTest.cpp | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/MobileGL/MG_Impl/Pipe/SlotAllocator.cpp b/MobileGL/MG_Impl/Pipe/SlotAllocator.cpp index 2c0b2a8d..906ae88c 100644 --- a/MobileGL/MG_Impl/Pipe/SlotAllocator.cpp +++ b/MobileGL/MG_Impl/Pipe/SlotAllocator.cpp @@ -322,6 +322,12 @@ namespace MobileGL::MG_Pipe { } MGPipeSlotAllocator& MGPipeSlots() { +#if MOBILEGL_BUILD_DISAGGREGATED + // Guard the client singleton itself too: Allocate/IsLive/HighWater and the + // bookkeeping accessors must not bypass the original three method guards. + // Backend-private allocator instances do not use this accessor. + MGPipeRefuseAllocatorFromApplyThread("client-singleton"); +#endif // NEVER DESTROYED, deliberately (one allocation for the life of the process). A // frontend object's destructor reaches this allocator - ~BufferObject through // MGPipeEmitResourceDestroyAndFree, ~VertexArrayObject through the death notice - and diff --git a/MobileGL/MG_Impl/Pipe/SlotAllocator.h b/MobileGL/MG_Impl/Pipe/SlotAllocator.h index 614d1ea3..b0e59384 100644 --- a/MobileGL/MG_Impl/Pipe/SlotAllocator.h +++ b/MobileGL/MG_Impl/Pipe/SlotAllocator.h @@ -166,7 +166,7 @@ namespace MobileGL::MG_Pipe { #if MOBILEGL_BUILD_DISAGGREGATED // P5c (hd, CONTRACT-P5C §3.1 / §6 layer 1): with an active transport this allocator is a - // CLIENT-only surface. Acquire, FindByLifetimeId and Free called from the apply thread - + // CLIENT-only surface. Its singleton accessor and original three method guards reject apply - // i.e. a server that resolves or mints handles off a frontend object's lifetime id (T2), // which is memory that will not exist on its side of a real split - are // Fatal{RoleViolation, "MGPipeSlots"}. Compiled out entirely outside split builds, so the @@ -180,7 +180,7 @@ namespace MobileGL::MG_Pipe { // P5f (fr): frontend-object twin lookup, minting and weak-state access are refused // on EVERY transport apply, including barriered records and both named scopes. // The handle overloads remain server-local; the frontend overloads remain monolith - // glue. This separate guard also prevents borrowing Magma's allocator exemption. + // glue. The registry guard is independent of the allocator guard. void MGPipeRefuseFrontendKeyedRegistryFromApplyThread(const char* entry); // P5f (fr): these historical scope names remain greppable markers around diff --git a/MobileGL/MG_Test/Wire/RemoteClientTest.cpp b/MobileGL/MG_Test/Wire/RemoteClientTest.cpp index 3bd50a3e..0e5dbf34 100644 --- a/MobileGL/MG_Test/Wire/RemoteClientTest.cpp +++ b/MobileGL/MG_Test/Wire/RemoteClientTest.cpp @@ -1957,7 +1957,8 @@ TEST(RemoteGuards, BarrieredLegacyScopesCannotExemptAllocator) { MG_Config::ActiveBackendType = *static_cast(self); const MG_Pipe::MGPipeFrontendKeyedRegistryScope registryScope; const MG_Pipe::MagmaP7AllocatorDebtScope magmaScope; - MGPipeSlots().FindByLifetimeId(MGPipeKind::Texture, 99); + // HighWater had no per-method guard in the old implementation. + (void)MGPipeSlots().HighWater(MGPipeKind::Texture); return MOBILEGL_OK; }, &selectedBackend); ClientSessionInstance().Stop();