From df8788ba5dc23da2bfda05c5a6139f5aadf08b85 Mon Sep 17 00:00:00 2001 From: Steven Massey Date: Tue, 17 Dec 2019 19:02:46 -0800 Subject: [PATCH] start of native-stack overflow detection API --- platforms/app_fuzz/fuzzer.c | 2 +- platforms/emscripten/main.c | 2 +- source/m3.h | 18 +++++++++++++++++- source/m3_compile.c | 24 ++++++++++++++---------- source/m3_env.c | 24 ++++++++++++++++++++++-- source/m3_exec.c | 12 +++++------- source/m3_exec.h | 2 +- 7 files changed, 61 insertions(+), 23 deletions(-) diff --git a/platforms/app_fuzz/fuzzer.c b/platforms/app_fuzz/fuzzer.c index a892514..94481a0 100644 --- a/platforms/app_fuzz/fuzzer.c +++ b/platforms/app_fuzz/fuzzer.c @@ -17,7 +17,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) IM3Environment env = m3_NewEnvironment (); if (env) { - IM3Runtime runtime = m3_NewRuntime (env, 64*1024); + IM3Runtime runtime = m3_NewRuntime (env, 64*1024, NULL); if (runtime) { IM3Module module = NULL; result = m3_ParseModule (env, &module, data, size); diff --git a/platforms/emscripten/main.c b/platforms/emscripten/main.c index ffefd26..e10bfd7 100644 --- a/platforms/emscripten/main.c +++ b/platforms/emscripten/main.c @@ -21,7 +21,7 @@ void run_wasm() IM3Environment env = m3_NewEnvironment (); if (!env) FATAL("m3_NewEnvironment failed"); - IM3Runtime runtime = m3_NewRuntime (env, 64*1024); + IM3Runtime runtime = m3_NewRuntime (env, 64*1024, NULL); if (!runtime) FATAL("m3_NewRuntime failed"); IM3Module module; diff --git a/source/m3.h b/source/m3.h index 7c75bbc..d2e0dac 100644 --- a/source/m3.h +++ b/source/m3.h @@ -65,6 +65,13 @@ typedef struct M3ErrorInfo M3ErrorInfo; +typedef struct M3StackInfo +{ + void * startAddr; + int stackSize; +} +M3StackInfo; + enum // EWaTypes { @@ -177,6 +184,14 @@ typedef int64_t (* M3Callback) (IM3Function i_currentFunction, void * i_ref); */ +//-------------------------------------------------------------------------------------------------------------------------------------------- +// initialization +//-------------------------------------------------------------------------------------------------------------------------------------------- + + M3StackInfo m3_GetNativeStackInfo (int i_stackSize); + // GetNativeStackInfo should be called at the start of main() or, if runtimes are used in a thread, at the start of the thread + // start function. + //-------------------------------------------------------------------------------------------------------------------------------------------- // global environment than can host multiple runtimes //-------------------------------------------------------------------------------------------------------------------------------------------- @@ -189,7 +204,8 @@ typedef int64_t (* M3Callback) (IM3Function i_currentFunction, void * i_ref); //-------------------------------------------------------------------------------------------------------------------------------------------- IM3Runtime m3_NewRuntime (IM3Environment io_environment, - uint32_t i_stackSizeInBytes); + uint32_t i_stackSizeInBytes, + M3StackInfo * i_nativeStackInfo); // i_nativeStackInfo can be NULL M3Result m3_RegisterFunction (IM3Runtime io_runtime, diff --git a/source/m3_compile.c b/source/m3_compile.c index 829c5e4..136404e 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -1547,7 +1547,7 @@ const M3OpInfo c_operations [] = M3OP( "br_table", -1, none, d_singleOp (BranchTable), Compile_BranchTable ), // 0x0e M3OP( "return", 0, any, d_singleOp (Return), Compile_Return ), // 0x0f M3OP( "call", 0, any, d_singleOp (Call), Compile_Call ), // 0x10 - M3OP( "call_indirect", 0, any, d_emptyOpList(), Compile_CallIndirect ), // 0x11 + M3OP( "call_indirect", 0, any, d_singleOp (CallIndirect), Compile_CallIndirect ), // 0x11 M3OP( "return_call", 0, any, d_emptyOpList(), Compile_Call ), // 0x12 TODO: Optimize M3OP( "return_call_indirect",0, any, d_emptyOpList(), Compile_CallIndirect ), // 0x13 @@ -1757,15 +1757,19 @@ const M3OpInfo c_operations [] = d_m3DebugOp (CopySlot_64), d_m3DebugOp (PreserveCopySlot_64), - d_m3DebugOp (SetSlot_i32), - d_m3DebugOp (SetSlot_i64), - d_m3DebugOp (SetSlot_f32), - d_m3DebugOp (SetSlot_f64), - - d_m3DebugOp (SetRegister_i32), d_m3DebugOp (i32_BranchIf_rs), - d_m3DebugOp (SetRegister_i64), d_m3DebugOp (i32_BranchIf_ss), - d_m3DebugOp (SetRegister_f32), d_m3DebugOp (i64_BranchIf_rs), - d_m3DebugOp (SetRegister_f64), d_m3DebugOp (i64_BranchIf_ss), + d_m3DebugOp (SetRegister_i32), d_m3DebugOp (i32_BranchIf_rs), d_m3DebugOp (SetSlot_i32), + d_m3DebugOp (SetRegister_i64), d_m3DebugOp (i32_BranchIf_ss), d_m3DebugOp (SetSlot_i64), + d_m3DebugOp (SetRegister_f32), d_m3DebugOp (i64_BranchIf_rs), d_m3DebugOp (SetSlot_f32), + d_m3DebugOp (SetRegister_f64), d_m3DebugOp (i64_BranchIf_ss), d_m3DebugOp (SetSlot_f64), + + d_m3DebugOp (Select_i32_rss), d_m3DebugOp (Select_i32_srs), d_m3DebugOp (Select_i32_ssr), d_m3DebugOp (Select_i32_sss), + d_m3DebugOp (Select_i64_rss), d_m3DebugOp (Select_i64_srs), d_m3DebugOp (Select_i64_ssr), d_m3DebugOp (Select_i64_sss), + + d_m3DebugOp (Select_f32_sss), d_m3DebugOp (Select_f32_srs), d_m3DebugOp (Select_f32_ssr), + d_m3DebugOp (Select_f32_rss), d_m3DebugOp (Select_f32_rrs), d_m3DebugOp (Select_f32_rsr), + + d_m3DebugOp (Select_f64_sss), d_m3DebugOp (Select_f64_srs), d_m3DebugOp (Select_f64_ssr), + d_m3DebugOp (Select_f64_rss), d_m3DebugOp (Select_f64_rrs), d_m3DebugOp (Select_f64_rsr), # endif diff --git a/source/m3_env.c b/source/m3_env.c index 25027bc..129c386 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -91,7 +91,7 @@ void m3_FreeEnvironment (IM3Environment i_environment) } -IM3Runtime m3_NewRuntime (IM3Environment i_environment, u32 i_stackSizeInBytes) +IM3Runtime m3_NewRuntime (IM3Environment i_environment, u32 i_stackSizeInBytes, M3StackInfo * i_nativeStackInfo) { IM3Runtime runtime = NULL; m3Alloc (& runtime, M3Runtime, 1); @@ -346,7 +346,7 @@ M3Result InitDataSegments (M3Memory * io_memory, IM3Module io_module) bytes_t start = segment->initExpr; _ (EvaluateExpression (io_module, & segmentOffset, c_m3Type_i32, & start, segment->initExpr + segment->initExprSize)); - u32 minMemorySize = segment->size + segmentOffset + 1; m3log (runtime, "loading data segment: %d offset: %d", i, segmentOffset); + u32 minMemorySize = segment->size + segmentOffset + 1; m3log (runtime, "loading data segment: %d; size: %d; offset: %d", i, segment->size, segmentOffset); //_ (Module_EnsureMemorySize (io_module, io_memory, minMemorySize)); @@ -827,3 +827,23 @@ void m3_IgnoreErrorInfo (IM3Runtime i_runtime) i_runtime->error = reset; } + +void GetStackInfo (M3StackInfo * io_info) +{ + io_info->startAddr = (void *) io_info; + + bool stackGrowsDown = false; + stackGrowsDown = io_info->startAddr > (void *) & stackGrowsDown; + + if (stackGrowsDown) + io_info->stackSize *= -1; +} + + +M3StackInfo m3_GetNativeStackInfo (int i_stackSize) +{ + M3StackInfo info = { NULL, (int) i_stackSize }; + GetStackInfo (& info); + + return info; +} diff --git a/source/m3_exec.c b/source/m3_exec.c index 98bcde2..43840c4 100644 --- a/source/m3_exec.c +++ b/source/m3_exec.c @@ -181,12 +181,12 @@ d_m3OpDef (Entry) if ((void *) _sp <= header->maxStack) { IM3Function function = immediate (IM3Function); - function->hits++; m3log (exec, " enter %p > %s %s", _pc - 2, function->name, SPrintFunctionArgList (function, _sp)); + function->hits++; m3log (exec, " enter %p > %s %s", _pc - 2, function->name ? function->name : ".unnamed", SPrintFunctionArgList (function, _sp)); u32 numLocals = function->numLocals; m3stack_t stack = _sp + GetFunctionNumArgs (function); - while (numLocals--) // it seems locals need to init to zero (at least for optimized Wasm code) + while (numLocals--) // it seems locals need to init to zero (at least for optimized Wasm code) TODO: see if this is still true. * (stack++) = 0; memcpy (stack, function->constants, function->numConstants * sizeof (u64)); @@ -202,11 +202,9 @@ d_m3OpDef (Entry) SPrintArg (str, 99, _sp, function->funcType->returnType); m3log (exec, " exit < %s %s %s %s", function->name, returnType ? "->" : "", str, r ? r : ""); -# endif - -# if d_m3LogStackTrace - if (r) - printf (" ** %s %p\n", function->name, _sp); +# elif d_m3LogStackTrace + if (r) + printf (" ** %s %p\n", function->name, _sp); # endif return r; diff --git a/source/m3_exec.h b/source/m3_exec.h index b569150..2f63205 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -48,7 +48,7 @@ d_m3RetSig Call (d_m3OpSig) { -// m3Yield (); + m3Yield (); return nextOpDirect(); }