From b290099572408f97f6e3ca546110291e433e4c8f Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 08:30:45 -0700 Subject: [PATCH 01/13] Intro concept of Identity exclusivity for handle_t --- core/logic/HandleSys.cpp | 3 +++ public/IHandleSys.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/core/logic/HandleSys.cpp b/core/logic/HandleSys.cpp index 10c9791c78..ca48639c35 100644 --- a/core/logic/HandleSys.cpp +++ b/core/logic/HandleSys.cpp @@ -532,6 +532,9 @@ bool HandleSystem::CheckAccess(QHandle *pHandle, HandleAccessRight right, const /* Check if the owner is allowed */ if (access & HANDLE_RESTRICT_OWNER) { + if ((access & HANDLE_RESTRICT_IDENTEXCLUSIVE) == HANDLE_RESTRICT_IDENTEXCLUSIVE) + return false; + IdentityToken_t *owner = pHandle->owner; if (owner && (!pSecurity || pSecurity->pOwner != owner)) diff --git a/public/IHandleSys.h b/public/IHandleSys.h index e2387b5835..cd84192e96 100644 --- a/public/IHandleSys.h +++ b/public/IHandleSys.h @@ -135,6 +135,8 @@ namespace SourceMod #define HANDLE_RESTRICT_IDENTITY (1<<0) /** Access is restricted to the owner */ #define HANDLE_RESTRICT_OWNER (1<<1) + /** Access is identity exclusive */ + #define HANDLE_RESTRICT_IDENTEXCLUSIVE (1<<2) /** * @brief This is used to define per-type access rights. From 45dd841330a0692ad41277653f28c8aaa52bb3c3 Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 08:32:13 -0700 Subject: [PATCH 02/13] Introduce GetHandleAccess to (I)HandleSys. --- core/logic/HandleSys.cpp | 13 +++++++++++++ core/logic/HandleSys.h | 2 ++ public/IHandleSys.h | 9 +++++++++ 3 files changed, 24 insertions(+) diff --git a/core/logic/HandleSys.cpp b/core/logic/HandleSys.cpp index ca48639c35..8a2f5d156b 100644 --- a/core/logic/HandleSys.cpp +++ b/core/logic/HandleSys.cpp @@ -1169,3 +1169,16 @@ void HandleSystem::Dump(const HandleReporter &fn) rep(fn, "-- Approximately %d bytes of memory are in use by Handles.\n", total_size); } +HandleError HandleSystem::GetHandleAccess(Handle_t handle, HandleAccess &*pAccess) +{ + unsigned int index; + QHandle *pHandle; + HandleError err; + IdentityToken_t *ident = NULL; + + if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None) + return err; + + pAccess = &(pHandle->sec); + return err; +} diff --git a/core/logic/HandleSys.h b/core/logic/HandleSys.h index 54e9175143..1ca35d2b22 100644 --- a/core/logic/HandleSys.h +++ b/core/logic/HandleSys.h @@ -173,6 +173,8 @@ class HandleSystem : /* Bypasses security checks. */ Handle_t FastCloneHandle(Handle_t hndl); + + HandleError GetHandleAccess(Handle_t handle, HandleAccess &*pSecurity); protected: /** * Decodes a handle with sanity and security checking. diff --git a/public/IHandleSys.h b/public/IHandleSys.h index cd84192e96..9edcad7691 100644 --- a/public/IHandleSys.h +++ b/public/IHandleSys.h @@ -375,6 +375,15 @@ namespace SourceMod * @return True if "given" is a subtype of "actual", false otherwise. */ virtual bool TypeCheck(HandleType_t given, HandleType_t actual) = 0; + + /** + * @brief Obtain the HandleAccess address from the passed in handle. + * + * @param handle Handle_t identifier to destroy. + * @param pAccess Access information struct. + * @return HandleError error code. + */ + virtual HandleError GetHandleAccess(Handle_t handle, HandleAccess &*pAccess) = 0; }; } From 60841f42b710b08cdafb8a5b0be180e3884ed23f Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 08:33:10 -0700 Subject: [PATCH 03/13] Add AutoHandleIdentLocker to pub/internal API --- core/logic/HandleSys.h | 39 +++++++++++++++++++++++++++++++++++++++ public/AutoHandleRooter.h | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/core/logic/HandleSys.h b/core/logic/HandleSys.h index 1ca35d2b22..8e10881f37 100644 --- a/core/logic/HandleSys.h +++ b/core/logic/HandleSys.h @@ -262,4 +262,43 @@ struct AutoHandleRooter Handle_t hndl; }; +struct AutoHandleIdentLocker +{ +public: + AutoHandleIdentLocker() : pSecurity(nullptr) + { + } + + AutoHandleIdentLocker(Handle_t hndl) : pSecurity(nullptr) + { + if (hndl != BAD_HANDLE) + { + if (g_HandleSys.GetHandleAccess(hndl, this->pSecurity) == HandleError_None) + { + if ((this->pSecurity[HandleAccess_Delete] & HANDLE_RESTRICT_IDENTEXCLUSIVE) == HANDLE_RESTRICT_IDENTEXCLUSIVE) + this->pSecurity = nullptr; + else + pSecurity->access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTEXCLUSIVE; + } + } + } + + ~AutoHandleIdentLocker() + { + if (this->pSecurity) + this->pSecurity->access[HandleAccess_Delete] &= ~HANDLE_RESTRICT_IDENTEXCLUSIVE; + + this->pSecurity = nullptr; + } + +public: + AutoHandleIdentLocker &operator =(const AutoHandleIdentLocker &other) + { + ~AutoHandleIdentLocker(); + this->pSecurity = other.pSecurity; + } +private: + HandleAccess *pSecurity; +} + #endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_H_ diff --git a/public/AutoHandleRooter.h b/public/AutoHandleRooter.h index d7aae7b0af..3c93699cc6 100644 --- a/public/AutoHandleRooter.h +++ b/public/AutoHandleRooter.h @@ -87,5 +87,44 @@ class AutoHandleCloner } }; +class AutoHandleIdentLocker +{ +public: + AutoHandleIdentLocker() : pSecurity(nullptr) + { + } + + AutoHandleIdentLocker(Handle_t hndl) : pSecurity(nullptr) + { + if (hndl != BAD_HANDLE) + { + if (handlesys->GetHandleAccess(hndl, this->pSecurity) == HandleError_None) + { + if ((this->pSecurity[HandleAccess_Delete] & HANDLE_RESTRICT_IDENTEXCLUSIVE) == HANDLE_RESTRICT_IDENTEXCLUSIVE) + this->pSecurity = nullptr; + else + pSecurity->access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTEXCLUSIVE; + } + } + } + + ~AutoHandleIdentLocker() + { + if (this->pSecurity) + this->pSecurity->access[HandleAccess_Delete] &= ~HANDLE_RESTRICT_IDENTEXCLUSIVE; + + this->pSecurity = nullptr; + } + +public: + AutoHandleIdentLocker &operator =(const AutoHandleIdentLocker &other) + { + ~AutoHandleIdentLocker(); + this->pSecurity = other.pSecurity; + } +private: + HandleAccess *pSecurity; +}; + #endif /* _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_ */ From 284a14f78b6ad959c4a0ef1409d6bac3ea678489 Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 08:34:00 -0700 Subject: [PATCH 04/13] functions: Lock Handle delete to Identity master --- core/logic/smn_functions.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/logic/smn_functions.cpp b/core/logic/smn_functions.cpp index 606b7855bb..d5addaea35 100644 --- a/core/logic/smn_functions.cpp +++ b/core/logic/smn_functions.cpp @@ -35,6 +35,7 @@ #include #include #include +#include HandleType_t g_GlobalFwdType = 0; HandleType_t g_PrivateFwdType = 0; @@ -43,6 +44,7 @@ static bool s_CallStarted = false; static ICallable *s_pCallable = NULL; static IPluginFunction *s_pFunction = NULL; static IForward *s_pForward = NULL; +static Handle_t s_ForwardHndl = BAD_HANDLE; class ForwardNativeHelpers : public SMGlobalClass, @@ -330,6 +332,7 @@ static cell_t sm_CallStartFunction(IPluginContext *pContext, const cell_t *param if (!s_pFunction) { + ResetCall(); return pContext->ThrowNativeError("Invalid function id (%X)", params[2]); } @@ -337,6 +340,8 @@ static cell_t sm_CallStartFunction(IPluginContext *pContext, const cell_t *param s_CallStarted = true; + s_ForwardHndl = hndl; + return 1; } @@ -362,6 +367,7 @@ static cell_t sm_CallStartForward(IPluginContext *pContext, const cell_t *params s_pCallable = static_cast(pForward); s_CallStarted = true; + s_ForwardHndl = hndl; return 1; } @@ -646,6 +652,7 @@ static cell_t sm_CallFinish(IPluginContext *pContext, const cell_t *params) pContext->LocalToPhysAddr(params[1], &result); + AutoHandleIdentLocker lock(s_ForwardHndl); // Note: Execute() swallows exceptions, so this is okay. if (s_pFunction) { From 86916f2b0d39ed80862710b28d06c36af89819e5 Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 08:43:50 -0700 Subject: [PATCH 05/13] typo-fix. --- core/logic/HandleSys.cpp | 2 +- core/logic/HandleSys.h | 2 +- public/IHandleSys.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/logic/HandleSys.cpp b/core/logic/HandleSys.cpp index 8a2f5d156b..851b324505 100644 --- a/core/logic/HandleSys.cpp +++ b/core/logic/HandleSys.cpp @@ -1169,7 +1169,7 @@ void HandleSystem::Dump(const HandleReporter &fn) rep(fn, "-- Approximately %d bytes of memory are in use by Handles.\n", total_size); } -HandleError HandleSystem::GetHandleAccess(Handle_t handle, HandleAccess &*pAccess) +HandleError HandleSystem::GetHandleAccess(Handle_t handle, HandleAccess *&pAccess) { unsigned int index; QHandle *pHandle; diff --git a/core/logic/HandleSys.h b/core/logic/HandleSys.h index 8e10881f37..04c0112651 100644 --- a/core/logic/HandleSys.h +++ b/core/logic/HandleSys.h @@ -174,7 +174,7 @@ class HandleSystem : /* Bypasses security checks. */ Handle_t FastCloneHandle(Handle_t hndl); - HandleError GetHandleAccess(Handle_t handle, HandleAccess &*pSecurity); + HandleError GetHandleAccess(Handle_t handle, HandleAccess *&pSecurity); protected: /** * Decodes a handle with sanity and security checking. diff --git a/public/IHandleSys.h b/public/IHandleSys.h index 9edcad7691..4661a2e0bb 100644 --- a/public/IHandleSys.h +++ b/public/IHandleSys.h @@ -383,7 +383,7 @@ namespace SourceMod * @param pAccess Access information struct. * @return HandleError error code. */ - virtual HandleError GetHandleAccess(Handle_t handle, HandleAccess &*pAccess) = 0; + virtual HandleError GetHandleAccess(Handle_t handle, HandleAccess *&pAccess) = 0; }; } From 0cd1258b6cc8aab3a0789a4e8f2860319932f799 Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 08:52:21 -0700 Subject: [PATCH 06/13] Move destructor to "Nuke". --- public/AutoHandleRooter.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/public/AutoHandleRooter.h b/public/AutoHandleRooter.h index 3c93699cc6..eb5ecb6225 100644 --- a/public/AutoHandleRooter.h +++ b/public/AutoHandleRooter.h @@ -110,18 +110,24 @@ class AutoHandleIdentLocker ~AutoHandleIdentLocker() { - if (this->pSecurity) - this->pSecurity->access[HandleAccess_Delete] &= ~HANDLE_RESTRICT_IDENTEXCLUSIVE; - - this->pSecurity = nullptr; + this->Nuke(); } public: AutoHandleIdentLocker &operator =(const AutoHandleIdentLocker &other) { - ~AutoHandleIdentLocker(); + this->Nuke(); this->pSecurity = other.pSecurity; } +private: + void Nuke(void) + { + if (this->pSecurity) + { + this->pSecurity->access[HandleAccess_Delete] &= ~HANDLE_RESTRICT_IDENTEXCLUSIVE; + this->pSecurity = nullptr; + } + } private: HandleAccess *pSecurity; }; From 1687b154e7353b22bf7b4dd7e2bfa9d4c069e3a6 Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 09:00:38 -0700 Subject: [PATCH 07/13] another go for wally... --- core/logic/HandleSys.h | 2 +- public/AutoHandleRooter.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/logic/HandleSys.h b/core/logic/HandleSys.h index 04c0112651..f3d25d6b6c 100644 --- a/core/logic/HandleSys.h +++ b/core/logic/HandleSys.h @@ -275,7 +275,7 @@ struct AutoHandleIdentLocker { if (g_HandleSys.GetHandleAccess(hndl, this->pSecurity) == HandleError_None) { - if ((this->pSecurity[HandleAccess_Delete] & HANDLE_RESTRICT_IDENTEXCLUSIVE) == HANDLE_RESTRICT_IDENTEXCLUSIVE) + if ((this->pSecurity->access[HandleAccess_Delete] & HANDLE_RESTRICT_IDENTEXCLUSIVE) == HANDLE_RESTRICT_IDENTEXCLUSIVE) this->pSecurity = nullptr; else pSecurity->access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTEXCLUSIVE; diff --git a/public/AutoHandleRooter.h b/public/AutoHandleRooter.h index eb5ecb6225..bf023a4d2d 100644 --- a/public/AutoHandleRooter.h +++ b/public/AutoHandleRooter.h @@ -100,10 +100,10 @@ class AutoHandleIdentLocker { if (handlesys->GetHandleAccess(hndl, this->pSecurity) == HandleError_None) { - if ((this->pSecurity[HandleAccess_Delete] & HANDLE_RESTRICT_IDENTEXCLUSIVE) == HANDLE_RESTRICT_IDENTEXCLUSIVE) + if ((this->pSecurity->access[HandleAccess_Delete] & HANDLE_RESTRICT_IDENTEXCLUSIVE) == HANDLE_RESTRICT_IDENTEXCLUSIVE) this->pSecurity = nullptr; else - pSecurity->access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTEXCLUSIVE; + this->pSecurity->access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTEXCLUSIVE; } } } From e9f01494636f940eba4011eba44f27c3efe8909d Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 09:06:38 -0700 Subject: [PATCH 08/13] operator fix --- public/AutoHandleRooter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/AutoHandleRooter.h b/public/AutoHandleRooter.h index bf023a4d2d..891cd4c059 100644 --- a/public/AutoHandleRooter.h +++ b/public/AutoHandleRooter.h @@ -118,7 +118,7 @@ class AutoHandleIdentLocker { this->Nuke(); this->pSecurity = other.pSecurity; - } + }; private: void Nuke(void) { From d32511d83e8f98a94a05c5f199c3db57b7274079 Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 09:10:40 -0700 Subject: [PATCH 09/13] should go lie down... --- core/logic/HandleSys.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/core/logic/HandleSys.h b/core/logic/HandleSys.h index f3d25d6b6c..2ed23ef7f8 100644 --- a/core/logic/HandleSys.h +++ b/core/logic/HandleSys.h @@ -285,18 +285,24 @@ struct AutoHandleIdentLocker ~AutoHandleIdentLocker() { - if (this->pSecurity) - this->pSecurity->access[HandleAccess_Delete] &= ~HANDLE_RESTRICT_IDENTEXCLUSIVE; - - this->pSecurity = nullptr; + this->Nuke(); } public: AutoHandleIdentLocker &operator =(const AutoHandleIdentLocker &other) { - ~AutoHandleIdentLocker(); + this->Nuke(); this->pSecurity = other.pSecurity; } +private: + void Nuke(void) + { + if (this->pSecurity) + { + this->pSecurity->access[HandleAccess_Delete] &= ~HANDLE_RESTRICT_IDENTEXCLUSIVE; + this->pSecurity = nullptr; + } + } private: HandleAccess *pSecurity; } From c732c8dc788e3fc816c6bc55dd64b54953475a78 Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 09:17:31 -0700 Subject: [PATCH 10/13] what a pain. --- core/logic/HandleSys.h | 3 ++- public/AutoHandleRooter.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/logic/HandleSys.h b/core/logic/HandleSys.h index 2ed23ef7f8..a9a515eb58 100644 --- a/core/logic/HandleSys.h +++ b/core/logic/HandleSys.h @@ -293,7 +293,8 @@ struct AutoHandleIdentLocker { this->Nuke(); this->pSecurity = other.pSecurity; - } + return *this; + }; private: void Nuke(void) { diff --git a/public/AutoHandleRooter.h b/public/AutoHandleRooter.h index 891cd4c059..3528a3a6d5 100644 --- a/public/AutoHandleRooter.h +++ b/public/AutoHandleRooter.h @@ -118,6 +118,7 @@ class AutoHandleIdentLocker { this->Nuke(); this->pSecurity = other.pSecurity; + return *this; }; private: void Nuke(void) From fa69f94e77a6c3761073f0c3b72fadb54d70856b Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 09:32:44 -0700 Subject: [PATCH 11/13] =?UTF-8?q?=F0=9F=A4=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/logic/HandleSys.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/logic/HandleSys.h b/core/logic/HandleSys.h index a9a515eb58..54161e436b 100644 --- a/core/logic/HandleSys.h +++ b/core/logic/HandleSys.h @@ -306,6 +306,6 @@ struct AutoHandleIdentLocker } private: HandleAccess *pSecurity; -} +}; #endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_H_ From c28d9052a4a048ac99473e6b634722a53349fb85 Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 11:09:45 -0700 Subject: [PATCH 12/13] handlesys: Bump SMINTERFACE_HANDLESYSTEM_VERSION 6 --- public/IHandleSys.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/IHandleSys.h b/public/IHandleSys.h index 4661a2e0bb..fe12a5824f 100644 --- a/public/IHandleSys.h +++ b/public/IHandleSys.h @@ -52,7 +52,7 @@ #include #define SMINTERFACE_HANDLESYSTEM_NAME "IHandleSys" -#define SMINTERFACE_HANDLESYSTEM_VERSION 5 +#define SMINTERFACE_HANDLESYSTEM_VERSION 6 /** Specifies no Identity */ #define DEFAULT_IDENTITY NULL From 155248a2a972f292b83914e1d7ea0b82c9950961 Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sun, 21 Jul 2019 12:11:47 -0700 Subject: [PATCH 13/13] handlesys: minor style clean. --- core/logic/HandleSys.cpp | 7 +++---- core/logic/HandleSys.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/core/logic/HandleSys.cpp b/core/logic/HandleSys.cpp index 851b324505..959473c222 100644 --- a/core/logic/HandleSys.cpp +++ b/core/logic/HandleSys.cpp @@ -1173,12 +1173,11 @@ HandleError HandleSystem::GetHandleAccess(Handle_t handle, HandleAccess *&pAcces { unsigned int index; QHandle *pHandle; - HandleError err; IdentityToken_t *ident = NULL; + HandleError err = GetHandle(handle, ident, &pHandle, &index); - if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None) - return err; + if (err == HandleError_None) + pAccess = &(pHandle->sec); - pAccess = &(pHandle->sec); return err; } diff --git a/core/logic/HandleSys.h b/core/logic/HandleSys.h index 54161e436b..f741bd051d 100644 --- a/core/logic/HandleSys.h +++ b/core/logic/HandleSys.h @@ -278,7 +278,7 @@ struct AutoHandleIdentLocker if ((this->pSecurity->access[HandleAccess_Delete] & HANDLE_RESTRICT_IDENTEXCLUSIVE) == HANDLE_RESTRICT_IDENTEXCLUSIVE) this->pSecurity = nullptr; else - pSecurity->access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTEXCLUSIVE; + this->pSecurity->access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTEXCLUSIVE; } } }