1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2025-01-30 19:52:17 +01:00

Yay, the nasty SourceHook bug is finally fixed!

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%4087
This commit is contained in:
Scott Ehlert 2005-07-07 18:21:32 +00:00
parent 2e38619370
commit c8d4189477
3 changed files with 62 additions and 0 deletions

View File

@ -5,6 +5,7 @@
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* Contributors: Scott "Damaged Soul" Ehlert
* ============================
*/
@ -299,6 +300,13 @@ namespace SourceHook
if (hookman == m_HookMans.end())
return false;
if (IsBadReadPtr(reinterpret_cast<char*>(adjustediface) + tmp.vtbl_offs, sizeof(char)))
{
hookman->vfnptrs.clear();
hookman->func(HA_Unregister, NULL);
return true;
}
void **cur_vtptr = *reinterpret_cast<void***>(
reinterpret_cast<char*>(adjustediface) + tmp.vtbl_offs);
void *cur_vfnptr = reinterpret_cast<void*>(cur_vtptr + tmp.vtbl_idx);
@ -465,6 +473,38 @@ namespace SourceHook
}
}
#if __linux__
// Windows has an implentation for this already, but Linux does not :(
static bool CSourceHookImpl::IsBadReadPtr(const void *ptr, size_t len)
{
void(*prevHandler)(int sig);
g_BadReadCalled = true;
if (setjmp(g_BadReadJmpBuffer))
return true;
prevHandler = signal(SIGSEGV, BadReadHandler);
volatile const char *p = reinterpret_cast<const char*>(ptr);
char dummy;
for (size_t i = 0; i < len; i++)
dummy = p[i];
g_BadReadCalled = false;
signal(SIGSEGV, prevHandler);
return false;
}
static void CSourceHookImpl::BadReadHandler(int sig)
{
if (m_BadReadCalled)
longjmp(m_BadReadJmpBuf, 1);
}
#endif
CSourceHookImpl::HookManInfoList::iterator CSourceHookImpl::FindHookMan(HookManInfoList::iterator begin,
HookManInfoList::iterator end, const char *proto, int vtblofs, int vtblidx)
{

View File

@ -13,6 +13,11 @@
#include "sourcehook.h"
#ifdef __linux__
#include <signal.h>
#include <setjmp.h>
#endif
// Set this to 1 to enable runtime code generation (faster)
#define SH_RUNTIME_CODEGEN 1
@ -77,6 +82,22 @@ namespace SourceHook
void RemoveCallClassPatch(CallClassInfo &cc, int vtbl_offs, int vtbl_idx);
void RemoveCallClassPatches(void *ifaceptr, int vtbl_offs, int vtbl_idx);
#ifdef __linux__
/**
* @brief Checks to see if a memory value can be read from a given pointer.
*
* @return True if the value can be read and false if it cannot.
*
* @param ptr The pointer to the memory value.
* @param len The length of the memory value to be read from the pointer.
*/
static bool IsBadReadPtr(const void *ptr, size_t len);
static void BadReadHandler(int sig);
bool m_BadReadCalled;
jmp_buf m_BadReadJmpBuf;
#endif
META_RES m_Status, m_PrevRes, m_CurRes;
const void *m_OrigRet;
const void *m_OverrideRet;

View File

@ -13,6 +13,7 @@
- Fixed "meta clear" not unloading all plugins.
- Fixed Metamod:Source loading plugins with a higher current API version.
- Fixed whitespace being parsed in metaplugins.ini.
- Fixed bug where SourceHook tried to patch already destroyed/unavailable memory.
- Bumped Plugin API version to 6.
2005/05/06 1.00-RC1: