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
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)
{
// original function is vtable[entry]

View File

@ -534,21 +534,24 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
CHECK_FUNCTION(func);
char *function=MF_GetAmxString(amx, params[3], 0, NULL);
char *classname=MF_GetAmxString(amx, params[2], 1, NULL);
// Fixes a buffer issue by copying locally the strings.
// 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
// create an entity, assign it the gamedll's class, hook it and destroy it
edict_t *Entity=CREATE_ENTITY();
CALL_GAME_ENTITY(PLID,classname,&Entity->v);
CALL_GAME_ENTITY(PLID,classname.chars(),&Entity->v);
if (Entity->pvPrivateData == NULL)
{
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;
}
@ -558,18 +561,18 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
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;
}
// Verify that the function is valid
// 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)
{
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;
}
@ -586,9 +589,9 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
pfwd->AddRef();
// 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;
@ -615,7 +618,7 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
}
// 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);
if (post)