From: Vlad Tsyrklevich Date: Thu, 30 Aug 2018 20:44:51 +0000 (+0000) Subject: SafeStack: Prevent OOB reads with mem intrinsics X-Git-Tag: llvmorg-8.0.0-rc1~9745 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2499aeead93a28cff56816c6ce7c093d227a0084;p=platform%2Fupstream%2Fllvm.git SafeStack: Prevent OOB reads with mem intrinsics Summary: Currently, the SafeStack analysis disallows out-of-bounds writes but not out-of-bounds reads for mem intrinsics like llvm.memcpy. This could cause leaks of pointers to the safe stack by leaking spilled registers/ frame pointers. Check for allocas used as source or destination pointers to mem intrinsics. Reviewers: eugenis Reviewed By: eugenis Subscribers: pcc, llvm-commits, kcc Differential Revision: https://reviews.llvm.org/D51334 llvm-svn: 341116 --- diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp index 60e2ddf..7b1c7fe 100644 --- a/llvm/lib/CodeGen/SafeStack.cpp +++ b/llvm/lib/CodeGen/SafeStack.cpp @@ -260,8 +260,14 @@ bool SafeStack::IsAccessSafe(Value *Addr, uint64_t AccessSize, bool SafeStack::IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U, const Value *AllocaPtr, uint64_t AllocaSize) { - // All MemIntrinsics have destination address in Arg0 and size in Arg2. - if (MI->getRawDest() != U) return true; + if (auto MTI = dyn_cast(MI)) { + if (MTI->getRawSource() != U && MTI->getRawDest() != U) + return true; + } else { + if (MI->getRawDest() != U) + return true; + } + const auto *Len = dyn_cast(MI->getLength()); // Non-constant size => unsafe. FIXME: try SCEV getRange. if (!Len) return false; diff --git a/llvm/test/Transforms/SafeStack/X86/memintrinsic-oob-read.ll b/llvm/test/Transforms/SafeStack/X86/memintrinsic-oob-read.ll new file mode 100644 index 0000000..90af6b3 --- /dev/null +++ b/llvm/test/Transforms/SafeStack/X86/memintrinsic-oob-read.ll @@ -0,0 +1,14 @@ +; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s +; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) + +; CHECK: __safestack_unsafe_stack_ptr +define void @oob_read(i8* %ptr) safestack { + %1 = alloca i8 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %ptr, i8* align 1 %1, i64 4, i1 false) + ret void +}