P5f fr: guard registry frontend surfaces before arm selection

This commit is contained in:
2026-09-19 23:46:40 -04:00
parent 7ce19da02b
commit df5ffe037e
2 changed files with 50 additions and 2 deletions
+22 -2
View File
@@ -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<StateBackendObjectRegistry*>(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(); }
@@ -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<MG_State::GLState::TextureObject2D>* texture; int operation; };
for (int operation = 0; operation != 3; ++operation) {
const auto child = RunInChild([operation] {
StartControlSession();
auto texture = MakeShared<MG_State::GLState::TextureObject2D>(48);
Registry registry;
Probe probe{&registry, &texture, operation};
Srv::ServerLoopInstance().RunProbeOnApplyThreadForTesting(+[](void* self) -> MobileGLResult {
auto& probe = *static_cast<Probe*>(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();