Fix a buffer issue in RegisterHam (#495)

* Fix a buffer issue in RegisterHam

* AString classname as well
This commit is contained in:
Vincent Herbet 2018-07-13 16:23:03 +02:00 committed by GitHub
parent 975d877800
commit 5f5d6f1d5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 12 deletions

View File

@ -39,7 +39,7 @@ public:
char *ent; // ent name that's being hooked char *ent; // ent name that's being hooked
int trampSize; int trampSize;
Hook(void **vtable_, int entry_, void *target_, bool voidcall, bool retbuf, int paramcount, char *name) : Hook(void **vtable_, int entry_, void *target_, bool voidcall, bool retbuf, int paramcount, const char *name) :
func(NULL), vtable(vtable_), entry(entry_), target(target_), exec(0), del(0), tramp(NULL), trampSize(0) func(NULL), vtable(vtable_), entry(entry_), target(target_), exec(0), del(0), tramp(NULL), trampSize(0)
{ {
// original function is vtable[entry] // original function is vtable[entry]

View File

@ -534,21 +534,24 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
CHECK_FUNCTION(func); CHECK_FUNCTION(func);
char *function=MF_GetAmxString(amx, params[3], 0, NULL); // Fixes a buffer issue by copying locally the strings.
char *classname=MF_GetAmxString(amx, params[2], 1, NULL); // REMOVE_ENTITY invokes pfnOnFreeEntPrivateData which plugins can hook and `function` and `classname` strings are used after that
// but it is pointing to the AMXX static buffer. Basically, hooking this forward and doing stuff inside could invalid all RegisterHam calls.
ke::AString function(MF_GetAmxString(amx, params[3], 0, NULL));
ke::AString classname(MF_GetAmxString(amx, params[2], 1, NULL));
// Check the entity // Check the entity
// create an entity, assign it the gamedll's class, hook it and destroy it // create an entity, assign it the gamedll's class, hook it and destroy it
edict_t *Entity=CREATE_ENTITY(); edict_t *Entity=CREATE_ENTITY();
CALL_GAME_ENTITY(PLID,classname,&Entity->v); CALL_GAME_ENTITY(PLID,classname.chars(),&Entity->v);
if (Entity->pvPrivateData == NULL) if (Entity->pvPrivateData == NULL)
{ {
REMOVE_ENTITY(Entity); REMOVE_ENTITY(Entity);
MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for \"%s\", hook for \"%s\" not active.",classname,function); MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for \"%s\", hook for \"%s\" not active.",classname.chars(),function.chars());
return 0; return 0;
} }
@ -558,18 +561,18 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
if (vtable == NULL) if (vtable == NULL)
{ {
MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve vtable for \"%s\", hook for \"%s\" not active.",classname,function); MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve vtable for \"%s\", hook for \"%s\" not active.",classname.chars(),function.chars());
return 0; return 0;
} }
// Verify that the function is valid // Verify that the function is valid
// Don't fail the plugin if this fails, just emit a normal error // Don't fail the plugin if this fails, just emit a normal error
int fwd=hooklist[func].makefunc(amx, function); int fwd=hooklist[func].makefunc(amx, function.chars());
if (fwd == -1) if (fwd == -1)
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Function %s not found.", function); MF_LogError(amx, AMX_ERR_NATIVE, "Function %s not found.", function.chars());
return 0; return 0;
} }
@ -586,9 +589,9 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
pfwd->AddRef(); pfwd->AddRef();
// We've passed all tests... // We've passed all tests...
if (strcmp(classname, "player") == 0 && enableSpecialBot) if (strcmp(classname.chars(), "player") == 0 && enableSpecialBot)
{ {
SpecialbotHandler.RegisterHamSpecialBot(amx, func, function, post, pfwd); SpecialbotHandler.RegisterHamSpecialBot(amx, func, function.chars(), post, pfwd);
} }
int **ivtable=(int **)vtable; int **ivtable=(int **)vtable;
@ -615,7 +618,7 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
} }
// If we got here, the function is not hooked // If we got here, the function is not hooked
Hook *hook = new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].needsretbuf, hooklist[func].paramcount, classname); Hook *hook = new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].needsretbuf, hooklist[func].paramcount, classname.chars());
hooks[func].append(hook); hooks[func].append(hook);
if (post) if (post)