From 3479e452deec53872fea35194580acd9a1ca81e2 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Tue, 3 Jul 2012 07:51:12 -0400 Subject: [PATCH] Fixed clientprefs prefab menu double free crash (bug 5374, r=asherkin). --- extensions/clientprefs/extension.cpp | 17 +++++++++++++++-- extensions/clientprefs/extension.h | 3 +++ extensions/clientprefs/menus.cpp | 9 +++++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/extensions/clientprefs/extension.cpp b/extensions/clientprefs/extension.cpp index 62605a23..97aa8f81 100644 --- a/extensions/clientprefs/extension.cpp +++ b/extensions/clientprefs/extension.cpp @@ -105,6 +105,7 @@ bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late) sharesys->AddNatives(myself, g_ClientPrefNatives); sharesys->RegisterLibrary(myself, "clientprefs"); + identity = sharesys->CreateIdentity(sharesys->CreateIdentType("ClientPrefs"), this); g_CookieManager.cookieDataLoadedForward = forwards->CreateForward("OnClientCookiesCached", ET_Ignore, 1, NULL, Param_Cell); g_CookieType = handlesys->CreateType("Cookie", @@ -124,7 +125,7 @@ bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late) NULL); IMenuStyle *style = menus->GetDefaultStyle(); - g_CookieManager.clientMenu = style->CreateMenu(&g_Handler, NULL); + g_CookieManager.clientMenu = style->CreateMenu(&g_Handler, identity); g_CookieManager.clientMenu->SetDefaultTitle("Client Settings:"); plsys->AddPluginsListener(&g_CookieManager); @@ -191,10 +192,17 @@ void ClientPrefs::SDK_OnUnload() forwards->ReleaseForward(g_CookieManager.cookieDataLoadedForward); - g_CookieManager.clientMenu->Destroy(); + HandleSecurity sec = HandleSecurity(identity, identity); + HandleError err = handlesys->FreeHandle(g_CookieManager.clientMenu->GetHandle(), &sec); + if (HandleError_None != err) + { + g_pSM->LogError(myself, "Error %d when attempting to free client menu handle", err); + } phrases->Destroy(); + sharesys->DestroyIdentity( identity ); + plsys->RemovePluginsListener(&g_CookieManager); playerhelpers->RemoveClientListener(&g_CookieManager); @@ -470,6 +478,11 @@ bool Translate(char *buffer, return true; } +IdentityToken_t *ClientPrefs::GetIdentity() const +{ + return identity; +} + const char *ClientPrefs::GetExtensionVerString() { return SM_FULL_VERSION; diff --git a/extensions/clientprefs/extension.h b/extensions/clientprefs/extension.h index 7421007e..074db23b 100644 --- a/extensions/clientprefs/extension.h +++ b/extensions/clientprefs/extension.h @@ -140,6 +140,8 @@ public: */ //virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength); #endif +public: + IdentityToken_t *GetIdentity() const; public: IDBDriver *Driver; IDatabase *Database; @@ -152,6 +154,7 @@ public: private: SourceHook::List cachedQueries; IMutex *queryMutex; + IdentityToken_t *identity; }; class CookieTypeHandler : public IHandleTypeDispatch diff --git a/extensions/clientprefs/menus.cpp b/extensions/clientprefs/menus.cpp index 3c9b6714..884d7ee1 100644 --- a/extensions/clientprefs/menus.cpp +++ b/extensions/clientprefs/menus.cpp @@ -57,7 +57,7 @@ void ClientMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int i return; } - IBaseMenu *submenu = menus->GetDefaultStyle()->CreateMenu(&g_AutoHandler, NULL); + IBaseMenu *submenu = menus->GetDefaultStyle()->CreateMenu(&g_AutoHandler, g_ClientPrefs.GetIdentity()); char message[256]; @@ -175,5 +175,10 @@ void AutoMenuHandler::OnMenuSelect(SourceMod::IBaseMenu *menu, int client, unsig void AutoMenuHandler::OnMenuEnd(IBaseMenu *menu, MenuEndReason reason) { - menu->Destroy(true); + HandleSecurity sec = HandleSecurity(g_ClientPrefs.GetIdentity(), g_ClientPrefs.GetIdentity()); + HandleError err = handlesys->FreeHandle(menu->GetHandle(), &sec); + if (HandleError_None != err) + { + g_pSM->LogError(myself, "Error %d when attempting to free automenu handle", err); + } }