[llvm] r239761 - Protection against stack-based memory corruption errors using SafeStack

Peter Collingbourne peter at pcc.me.uk
Mon Jun 22 13:31:54 PDT 2015


On Mon, Jun 22, 2015 at 08:01:51PM +0200, Tobias Grosser wrote:
> On 06/15/2015 11:07 PM, Peter Collingbourne wrote:
>> Author: pcc
>> Date: Mon Jun 15 16:07:11 2015
>> New Revision: 239761
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=239761&view=rev
>> Log:
>> Protection against stack-based memory corruption errors using SafeStack
>>
>> This patch adds the safe stack instrumentation pass to LLVM, which separates
>> the program stack into a safe stack, which stores return addresses, register
>> spills, and local variables that are statically verified to be accessed
>> in a safe way, and the unsafe stack, which stores everything else. Such
>> separation makes it much harder for an attacker to corrupt objects on the
>> safe stack, including function pointers stored in spilled registers and
>> return addresses. You can find more information about the safe stack, as
>> well as other parts of or control-flow hijack protection technique in our
>> OSDI paper on code-pointer integrity (http://dslab.epfl.ch/pubs/cpi.pdf)
>> and our project website (http://levee.epfl.ch).
>>
>> The overhead of our implementation of the safe stack is very close to zero
>> (0.01% on the Phoronix benchmarks). This is lower than the overhead of
>> stack cookies, which are supported by LLVM and are commonly used today,
>> yet the security guarantees of the safe stack are strictly stronger than
>> stack cookies. In some cases, the safe stack improves performance due to
>> better cache locality.
>>
>> Our current implementation of the safe stack is stable and robust, we
>> used it to recompile multiple projects on Linux including Chromium, and
>> we also recompiled the entire FreeBSD user-space system and more than 100
>> packages. We ran unit tests on the FreeBSD system and many of the packages
>> and observed no errors caused by the safe stack. The safe stack is also fully
>> binary compatible with non-instrumented code and can be applied to parts of
>> a program selectively.
>>
>> This patch is our implementation of the safe stack on top of LLVM. The
>> patches make the following changes:
>>
>> - Add the safestack function attribute, similar to the ssp, sspstrong and
>>    sspreq attributes.
>>
>> - Add the SafeStack instrumentation pass that applies the safe stack to all
>>    functions that have the safestack attribute. This pass moves all unsafe local
>>    variables to the unsafe stack with a separate stack pointer, whereas all
>>    safe variables remain on the regular stack that is managed by LLVM as usual.
>>
>> - Invoke the pass as the last stage before code generation (at the same time
>>    the existing cookie-based stack protector pass is invoked).
>>
>> - Add unit tests for the safe stack.
>>
>> Original patch by Volodymyr Kuznetsov and others at the Dependable Systems
>> Lab at EPFL; updates and upstreaming by myself.
>
> Hi Peter,
>
> after this patch I get compilation errors in my CUDA kernel extractor  
> that say:
>
> 	Undefined reference to '__safestack_unsafe_stack_ptr' in ''
>
> This seems to be the culprit:
>
>
>> +  virtual bool doInitialization(Module &M) {
>> +    DL = &M.getDataLayout();
>> +
>> +    StackPtrTy = Type::getInt8PtrTy(M.getContext());
>> +    IntPtrTy = DL->getIntPtrType(M.getContext());
>> +    Int32Ty = Type::getInt32Ty(M.getContext());
>> +    Int8Ty = Type::getInt8Ty(M.getContext());
>> +
>> +    UnsafeStackPtr = getOrCreateUnsafeStackPtr(M);
>
> We add the StackPtr Global even though not a single safestack attribute  
> was added in the module. Besides adding unnecessary noise (a global  
> without any use), this also breaks the execution on NVIDIA GPUs as they  
> abort with the error above.
>
> If I comment out the above line, my code starts working again.
>
> Any chance, this attribute can just be added on demand?

Done; r240321.

Thanks,
-- 
Peter



More information about the llvm-commits mailing list