[PATCH] Protection against stack-based memory corruption errors using SafeStack
Peter Collingbourne
peter at pcc.me.uk
Tue May 19 12:39:50 PDT 2015
================
Comment at: include/llvm/Analysis/TargetTransformInfo.h:507
@@ +506,3 @@
+ /// space, and populates the address space and offset as appropriate.
+ bool getUnsafeStackPtrLocation(unsigned &AddressSpace,
+ unsigned &Offset) const;
----------------
kcc wrote:
> Do we need this at all?
Removed. We can easily restore this hook if we ever need it.
================
Comment at: lib/CodeGen/LLVMBuild.txt:25
@@ -24,2 +24,2 @@
parent = Libraries
-required_libraries = Analysis Core MC Scalar Support Target TransformUtils
+required_libraries = Analysis Core Instrumentation MC Scalar Support Target TransformUtils
----------------
kcc wrote:
> why do you need this?
Because the CodeGen library now depends on the `createSafeStackPass` function declared in Instrumentation.
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:105
@@ +104,3 @@
+
+ /* fallthough */
+
----------------
kcc wrote:
> Maybe this?
> http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
Done, introducing a macro LLVM_FALLTHROUGH in `llvm/Support/Compiler.h` because of r234788.
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:163
@@ +162,3 @@
+/// local variables that are accessed in unsafe ways.
+class SafeStack : public ModulePass {
+ const DataLayout *DL;
----------------
kcc wrote:
> does it have to be a module pass?
> why not a function pass?
It can be a function pass; done.
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:244
@@ +243,3 @@
+
+ // Check where the unsafe stack pointer is stored on this architecture
+ unsigned AddressSpace, Offset;
----------------
kcc wrote:
> here and elsewhere: period after a comment.
Done
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:249
@@ +248,3 @@
+ // (usually in the thread control block)
+ Constant *OffsetVal = ConstantInt::get(Int32Ty, Offset);
+ return ConstantExpr::getIntToPtr(
----------------
kcc wrote:
> why int32 here?
This code is now gone.
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:252
@@ +251,3 @@
+ OffsetVal, Int8Ty->getPointerTo()->getPointerTo(AddressSpace));
+ } else {
+ // The unsafe stack pointer is stored in a global variable with a magic name
----------------
kcc wrote:
> which of the ways is used where? do we need both?
The first code path was associated with the `getUnsafeStackPtrLocation` hook, which is now gone, so I've removed it.
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:256
@@ +255,3 @@
+ // FIXME: make the name start with "llvm."
+ static const char* unsafe_stack_ptr_var = "__safestack_unsafe_stack_ptr";
+
----------------
kcc wrote:
> const variables are named like kUnsafeStackPtrVar
Done
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:271
@@ +270,3 @@
+ // The variable exists, check its type and attributes
+ if (UnsafeStackPtr->getValueType() != Int8Ty->getPointerTo()) {
+ report_fatal_error(Twine(unsafe_stack_ptr_var) +
----------------
kcc wrote:
> why not just assert?
It is possible to fail these checks with "valid" (modulo the use of reserved identifiers) C translation units. Consider for example the following translation unit which uses `__safestack_unsafe_stack_ptr` as both a regular and thread-local variable.
```
void *__safestack_unsafe_stack_ptr = 0;
void f(char *);
void g() {
char foo[64];
f(foo);
}
```
Rather than asserting (or crashing horribly later in non-asserts builds), it would be better to abort early with `report_fatal_error`.
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:286
@@ +285,3 @@
+
+bool SafeStack::runOnFunction(Function &F) {
+ ++NumFunctions;
----------------
kcc wrote:
> This function is too big. Please split it into as many smaller ones as possible. With comments.
Done
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:289
@@ +288,3 @@
+
+ unsigned StackAlignment = 16;
+ Constant *UnsafeStackPtr = getOrCreateUnsafeStackPtr(F);
----------------
kcc wrote:
> const?
Now an enum
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:328
@@ +327,3 @@
+ if (CI->getCalledFunction() && CI->canReturnTwice())
+ //CI->getCalledFunction()->getName() == "_setjmp")
+ StackRestorePoints.push_back(CI);
----------------
kcc wrote:
> do you need this comment?
Removed
================
Comment at: lib/Transforms/Instrumentation/SafeStack.cpp:541
@@ +540,3 @@
+ Value *CurrentTop = DynamicTop ? IRB.CreateLoad(DynamicTop) : StaticTop;
+ IRB.CreateStore(CurrentTop, UnsafeStackPtr);
+ }
----------------
kcc wrote:
> Is this tested in any of the unit tests?
This is now covered by `setjmp.ll` and `setjmp2.ll`.
================
Comment at: test/Transforms/SafeStack/safestack.ll:1
@@ +1,2 @@
+; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck --check-prefix=CHECK --check-prefix=LINUX %s
+; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=CHECK --check-prefix=LINUX %s
----------------
kcc wrote:
> A comment would be nice.
> Explain why you have CHECK and LINUX
> Consider splitting this test into several
> Explain why you have CHECK and LINUX
The latter was testing the non-`getUnsafeStackPtrLocation` case, which is now the only case; removed.
> Consider splitting this test into several
Done
http://reviews.llvm.org/D6094
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
More information about the llvm-commits
mailing list