From: Thomas Lively Date: Tue, 21 Jun 2016 18:43:07 +0000 (-0700) Subject: Inserted local redzones. X-Git-Tag: android-x86-7.1-r1~148^2~212 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=227c9f39303e6357adcfeb4b94a905681f3616f0;p=android-x86%2Fexternal-swiftshader.git Inserted local redzones. BUG=chromium:https://bugs.chromium.org/p/nativeclient/issues/detail?id=4374 R=kschimpf@google.com, stichnot@chromium.org Review URL: https://codereview.chromium.org/2086593002 . --- diff --git a/docs/ASAN.rst b/docs/ASAN.rst index cd9748acb..5526c59b2 100644 --- a/docs/ASAN.rst +++ b/docs/ASAN.rst @@ -27,7 +27,3 @@ AddressSanitizer and properly linked into a final executable using subzero/pydir/szbuild.py with the --fsanitize-address flag, i.e.:: pydir/szbuild.py --fsanitize-address hello.pexe - - - - diff --git a/runtime/szrt_asan.c b/runtime/szrt_asan.c index 47b6abc8c..9f62e28ef 100644 --- a/runtime/szrt_asan.c +++ b/runtime/szrt_asan.c @@ -15,26 +15,49 @@ /// //===----------------------------------------------------------------------===// +#include #include +#include #include +static __thread int behind_malloc = 0; + // TODO(tlively): Define and implement this library void __asan_init(void) { - printf("Set up shadow memory here\n"); - return; + if (behind_malloc == 0) + printf("set up shadow memory here\n"); } void __asan_check(void *addr, int size) { - printf("Check %d bytes at %p\n", size, addr); - return; + if (behind_malloc == 0) + printf("check %d bytes at %p\n", size, addr); } void *__asan_malloc(size_t size) { - printf("malloc() called with size %d\n", size); - return malloc(size); + if (behind_malloc == 0) + printf("malloc() called with size %d\n", size); + ++behind_malloc; + void *ret = malloc(size); + --behind_malloc; + assert(behind_malloc >= 0); + return ret; } void __asan_free(void *ptr) { - printf("free() called on %p\n", ptr); + if (behind_malloc == 0) + printf("free() called on %p\n", ptr); + ++behind_malloc; free(ptr); + --behind_malloc; + assert(behind_malloc >= 0); +} + +void __asan_alloca(void *ptr, int size) { + if (behind_malloc == 0) + printf("alloca of %d bytes at %p\n", size, ptr); +} + +void __asan_unalloca(void *ptr, int size) { + if (behind_malloc == 0) + printf("unalloca of %d bytes as %p\n", size, ptr); } diff --git a/src/IceASanInstrumentation.cpp b/src/IceASanInstrumentation.cpp index 9bd955539..f4b47e15f 100644 --- a/src/IceASanInstrumentation.cpp +++ b/src/IceASanInstrumentation.cpp @@ -15,6 +15,7 @@ #include "IceASanInstrumentation.h" #include "IceBuildDefs.h" +#include "IceCfg.h" #include "IceCfgNode.h" #include "IceGlobalInits.h" #include "IceInst.h" @@ -122,6 +123,43 @@ ASanInstrumentation::createRz(VariableDeclarationList *List, return Rz; } +// Check for an alloca signaling the presence of local variables and add a +// redzone if it is found +void ASanInstrumentation::instrumentFuncStart(LoweringContext &Context) { + auto *FirstAlloca = llvm::dyn_cast(Context.getCur()); + if (FirstAlloca == nullptr) + return; + + constexpr SizeT Alignment = 4; + InstAlloca *RzAlloca = createLocalRz(Context, RzSize, Alignment); + + // insert before the current instruction + InstList::iterator Next = Context.getNext(); + Context.setInsertPoint(Context.getCur()); + Context.insert(RzAlloca); + Context.setNext(Next); +} + +void ASanInstrumentation::instrumentAlloca(LoweringContext &Context, + InstAlloca *Instr) { + auto *VarSizeOp = llvm::dyn_cast(Instr->getSizeInBytes()); + SizeT VarSize = (VarSizeOp == nullptr) ? RzSize : VarSizeOp->getValue(); + SizeT Padding = Utils::OffsetToAlignment(VarSize, RzSize); + constexpr SizeT Alignment = 1; + InstAlloca *Rz = createLocalRz(Context, RzSize + Padding, Alignment); + Context.insert(Rz); +} + +InstAlloca *ASanInstrumentation::createLocalRz(LoweringContext &Context, + SizeT Size, SizeT Alignment) { + Cfg *Func = Context.getNode()->getCfg(); + Variable *Rz = Func->makeVariable(IceType_i32); + Rz->setName(Func, nextRzName()); + auto *ByteCount = ConstantInteger32::create(Ctx, IceType_i32, Size); + auto *RzAlloca = InstAlloca::create(Func, Rz, ByteCount, Alignment); + return RzAlloca; +} + void ASanInstrumentation::instrumentCall(LoweringContext &Context, InstCall *Instr) { auto *CallTarget = diff --git a/src/IceASanInstrumentation.h b/src/IceASanInstrumentation.h index e1222b4ff..2cf5c59cb 100644 --- a/src/IceASanInstrumentation.h +++ b/src/IceASanInstrumentation.h @@ -31,7 +31,7 @@ class ASanInstrumentation : public Instrumentation { ASanInstrumentation &operator=(const ASanInstrumentation &) = delete; public: - ASanInstrumentation(GlobalContext *Ctx) : Instrumentation(Ctx) {} + ASanInstrumentation(GlobalContext *Ctx) : Instrumentation(Ctx), RzNum(0) {} void instrumentGlobals(VariableDeclarationList &Globals) override; private: @@ -40,13 +40,17 @@ private: VariableDeclaration *RzArray, SizeT &RzArraySize, VariableDeclaration *Global); + InstAlloca *createLocalRz(LoweringContext &Context, SizeT Size, + SizeT Alignment); + void instrumentFuncStart(LoweringContext &Context) override; + void instrumentAlloca(LoweringContext &Context, InstAlloca *Instr) override; void instrumentCall(LoweringContext &Context, InstCall *Instr) override; void instrumentLoad(LoweringContext &Context, InstLoad *Instr) override; void instrumentStore(LoweringContext &Context, InstStore *Instr) override; void instrumentAccess(LoweringContext &Context, Operand *Op, SizeT Size); void instrumentStart(Cfg *Func) override; bool DidInsertRedZones = false; - uint32_t RzNum = 0; + std::atomic RzNum; }; } // end of namespace Ice diff --git a/src/IceInstrumentation.cpp b/src/IceInstrumentation.cpp index b4229f6da..64a6212c0 100644 --- a/src/IceInstrumentation.cpp +++ b/src/IceInstrumentation.cpp @@ -31,12 +31,16 @@ void Instrumentation::instrumentFunc(Cfg *Func) { // TODO(tlively): More selectively instrument functions so that shadow memory // represents user accessibility more and library accessibility less. + bool DidInstrumentStart = false; LoweringContext Context; Context.init(Func->getNodes().front()); - instrumentFuncStart(Context); for (CfgNode *Node : Func->getNodes()) { Context.init(Node); while (!Context.atEnd()) { + if (!DidInstrumentStart) { + instrumentFuncStart(Context); + DidInstrumentStart = true; + } instrumentInst(Context); // go to next undeleted instruction Context.advanceCur(); diff --git a/src/IceInstrumentation.h b/src/IceInstrumentation.h index d41a7eeed..60afef7ee 100644 --- a/src/IceInstrumentation.h +++ b/src/IceInstrumentation.h @@ -47,7 +47,7 @@ public: private: void instrumentInst(LoweringContext &Context); virtual void instrumentFuncStart(LoweringContext &) {} - virtual void instrumentAlloca(LoweringContext &, const class InstAlloca *) {} + virtual void instrumentAlloca(LoweringContext &, class InstAlloca *) {} virtual void instrumentArithmetic(LoweringContext &, class InstArithmetic *) { } virtual void instrumentBr(LoweringContext &, class InstBr *) {} diff --git a/tests_lit/asan_tests/instrumentload.ll b/tests_lit/asan_tests/instrumentload.ll index f3c02bf4f..55a11dfef 100644 --- a/tests_lit/asan_tests/instrumentload.ll +++ b/tests_lit/asan_tests/instrumentload.ll @@ -69,12 +69,7 @@ define internal void @doLoads() { ; DUMP-LABEL: ================ Instrumented CFG ================ ; DUMP-NEXT: define internal void @doLoads() { ; DUMP-NEXT: __0: -; DUMP-NEXT: %srcLocal8 = alloca i8, i32 1, align 4 -; DUMP-NEXT: %srcLocal16 = alloca i8, i32 2, align 4 -; DUMP-NEXT: %srcLocal32 = alloca i8, i32 4, align 4 -; DUMP-NEXT: %srcLocal64 = alloca i8, i32 8, align 4 -; DUMP-NEXT: %srcLocal128 = alloca i8, i32 16, align 4 -; DUMP-NEXT: call void @__asan_check(i32 @srcConst8, i32 1) +; DUMP: call void @__asan_check(i32 @srcConst8, i32 1) ; DUMP-NEXT: %dest1 = load i8, i8* @srcConst8, align 1 ; DUMP-NEXT: call void @__asan_check(i32 @srcConst16, i32 2) ; DUMP-NEXT: %dest2 = load i16, i16* @srcConst16, align 1 diff --git a/tests_lit/asan_tests/instrumentlocals.ll b/tests_lit/asan_tests/instrumentlocals.ll new file mode 100644 index 000000000..1031382e6 --- /dev/null +++ b/tests_lit/asan_tests/instrumentlocals.ll @@ -0,0 +1,48 @@ +; Test for insertion of redzones around global variables + +; REQUIRES: allow_dump + +; RUN: %p2i -i %s --args -verbose=inst -threads=0 -fsanitize-address \ +; RUN: | FileCheck --check-prefix=DUMP %s + +; Function with local variables to be instrumented +define internal void @func() { + %local0 = alloca i8, i32 4, align 4 + %local1 = alloca i8, i32 32, align 4 + %local2 = alloca i8, i32 13, align 4 + %local3 = alloca i8, i32 75, align 4 + %local4 = alloca i8, i32 64, align 4 + %local5 = alloca i8, i32 4, align 1 + %local6 = alloca i8, i32 32, align 1 + %local7 = alloca i8, i32 13, align 1 + %local8 = alloca i8, i32 75, align 1 + %local9 = alloca i8, i32 64, align 1 + ret void +} + +; DUMP-LABEL: ================ Instrumented CFG ================ +; DUMP-NEXT: define internal void @func() { +; DUMP-NEXT: __0: +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 32, align 4 +; DUMP-NEXT: %local0 = alloca i8, i32 4, align 4 +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 60, align 1 +; DUMP-NEXT: %local1 = alloca i8, i32 32, align 4 +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 32, align 1 +; DUMP-NEXT: %local2 = alloca i8, i32 13, align 4 +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 51, align 1 +; DUMP-NEXT: %local3 = alloca i8, i32 75, align 4 +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 53, align 1 +; DUMP-NEXT: %local4 = alloca i8, i32 64, align 4 +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 32, align 1 +; DUMP-NEXT: %local5 = alloca i8, i32 4, align 1 +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 60, align 1 +; DUMP-NEXT: %local6 = alloca i8, i32 32, align 1 +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 32, align 1 +; DUMP-NEXT: %local7 = alloca i8, i32 13, align 1 +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 51, align 1 +; DUMP-NEXT: %local8 = alloca i8, i32 75, align 1 +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 53, align 1 +; DUMP-NEXT: %local9 = alloca i8, i32 64, align +; DUMP-NEXT: %__$rz{{[0-9]+}} = alloca i8, i32 32, align 1 +; DUMP-NEXT: ret void +; DUMP-NEXT: } diff --git a/tests_lit/asan_tests/instrumentstore.ll b/tests_lit/asan_tests/instrumentstore.ll index 73d0b9ea3..c81edac17 100644 --- a/tests_lit/asan_tests/instrumentstore.ll +++ b/tests_lit/asan_tests/instrumentstore.ll @@ -50,12 +50,7 @@ define internal void @doStores(<4 x i32> %vecSrc) { ; DUMP-LABEL: ================ Instrumented CFG ================ ; DUMP-NEXT: define internal void @doStores(<4 x i32> %vecSrc) { ; DUMP-NEXT: __0: -; DUMP-NEXT: %destLocal8 = alloca i8, i32 1, align 4 -; DUMP-NEXT: %destLocal16 = alloca i8, i32 2, align 4 -; DUMP-NEXT: %destLocal32 = alloca i8, i32 4, align 4 -; DUMP-NEXT: %destLocal64 = alloca i8, i32 8, align 4 -; DUMP-NEXT: %destLocal128 = alloca i8, i32 16, align 4 -; DUMP-NEXT: call void @__asan_check(i32 @destGlobal8, i32 1) +; DUMP: call void @__asan_check(i32 @destGlobal8, i32 1) ; DUMP-NEXT: store i8 42, i8* @destGlobal8, align 1 ; DUMP-NEXT: call void @__asan_check(i32 @destGlobal16, i32 2) ; DUMP-NEXT: store i16 42, i16* @destGlobal16, align 1