3 #include "tizenasanenv.h"
6 template <typename Type, int STACK_SIZE>
8 // We don't create constructor because
9 // this class is used in a zeroed memory area
13 _ASSERTE(m_pos < STACK_SIZE);
15 m_data[m_pos++] = addr;
28 return m_data[m_pos - 1];
38 Type m_data[STACK_SIZE];
42 struct AuxiliaryCalls {
44 void (*pushAddr)(LPVOID addr);
53 extern "C" void __sanitizer_disable_interceptors();
54 extern "C" void __sanitizer_enable_interceptors();
55 extern "C" bool __sanitizer_interceptors_are_enabled();
57 extern LPVOID tizenASanWrapper;
58 extern UINT32 tizenASanWrapperSize;
59 extern UINT32 tizenASanWrapperEntryOffset;
61 // The maximum nesting of transitions between managed and unmanaged code that we support.
62 // This number is estimated from the common sense. We think this is enough to check any
63 // sane code (if it is not recursive) and it won't bloat TLS. We do not use dynamic
64 // allocation because it complicates the process of memory management in TLS variables.
65 // It is used only for firmware with ASan and will not affect the release version.
66 #define MAX_STACK_DEPTH 128
67 static __thread StaticStack<ReturnInfo, MAX_STACK_DEPTH> s_retInfoStack;
70 static void DoEnable()
72 _ASSERTE(__sanitizer_interceptors_are_enabled() == false);
73 __sanitizer_enable_interceptors();
76 static void DoDisable()
78 _ASSERTE(__sanitizer_interceptors_are_enabled() == true);
79 __sanitizer_disable_interceptors();
82 static void PushAndEnableASan(LPVOID addr)
84 _ASSERTE(__sanitizer_interceptors_are_enabled() == false);
86 ReturnInfo retInfo = {
91 s_retInfoStack.push(retInfo);
95 static LPVOID PopAndDisableASan()
97 _ASSERTE(__sanitizer_interceptors_are_enabled() == true);
99 ReturnInfo retInfo = s_retInfoStack.top();
100 s_retInfoStack.pop();
102 _ASSERTE(retInfo.isSanitized == false);
108 static void PushAndMayBeDisableASan(LPVOID addr)
110 ReturnInfo retInfo = {
112 .isSanitized = __sanitizer_interceptors_are_enabled(),
115 if (retInfo.isSanitized)
118 s_retInfoStack.push(retInfo);
121 static LPVOID PopAndMayBeEnableASan()
123 _ASSERTE(__sanitizer_interceptors_are_enabled() == false);
125 ReturnInfo retInfo = s_retInfoStack.top();
126 s_retInfoStack.pop();
128 if (retInfo.isSanitized)
134 static LPVOID CreateWrapper(LPVOID target, void (*pushAddr)(LPVOID addr), LPVOID (*popAddr)())
136 _ASSERTE(tizenASanWrapperEntryOffset == sizeof(AuxiliaryCalls));
138 LPVOID wrapperSpace = (LPVOID)SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap()->AllocMem(S_SIZE_T(tizenASanWrapperSize));
140 AuxiliaryCalls calls = {
142 .pushAddr = pushAddr,
146 // copy auxiliary calls
147 memcpy(wrapperSpace, &calls, sizeof(calls));
149 LPVOID entryPointer = (LPVOID)((UINT_PTR)wrapperSpace + tizenASanWrapperEntryOffset);
150 LPVOID wrapperEntryPointer = (LPVOID)((UINT_PTR)&tizenASanWrapper + tizenASanWrapperEntryOffset);
151 UINT32 wrapperCodeSize = tizenASanWrapperSize - tizenASanWrapperEntryOffset;
153 // copy executable code wrapper
154 memcpy(entryPointer, wrapperEntryPointer, wrapperCodeSize);
156 FlushInstructionCache(GetCurrentProcess(), wrapperSpace, tizenASanWrapperSize);
162 namespace TizenASanEnv {
164 LPVOID CreateWrapperSanitizedEntryPoint(LPVOID target)
166 return CreateWrapper(target, PushAndEnableASan, PopAndDisableASan);
169 LPVOID CreateWrapperILCode(LPVOID target)
171 return CreateWrapper(target, PushAndMayBeDisableASan, PopAndMayBeEnableASan);
174 } // namespace TizenASanEnv