LE: indeed, it's quite clear from the mentioned article (http://dslab.epfl.ch/pubs/cpi.pdf). So this provides great exploit protection.
> With SafeStack alone, an attacker can overwrite a function pointer on the heap or the unsafe stack and cause a program to call arbitrary location, which in turn might enable stack pivoting and return-oriented programming.
And you need additional features (such as CPI from the paper you and the commit message link to) for full protection.
It's used as a way to defeat DEP (Data Execution Prevention); with DEP the attacker can no longer write code into memory and then execute it, so instead they just set up the stack cleverly so they can carry out a return-oriented payload (most commonly, these payloads just disable DEP and then move on to a more traditional second stage).
More info:
The paper that introduced the name ROP (though some would argue that the techniques existed before this paper): https://cseweb.ucsd.edu/~hovav/dist/geometry.pdf
Wikipedia: https://en.wikipedia.org/wiki/Return-oriented_programming
"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."
Win-win for everyone
> This is because objects that end up being moved to the regular (unsafe) stack are usually large arrays or variables that are used through multiple stack frames. Moving such objects away from the safe stack increases the locality of frequently accessed values on the stack, such as CPU register values temporarily stored on the stack, return ad- dresses, and small local variables.
I wonder if this speedup effectively hides the performance overhead of SafeStack.
Google will be able to do likewise for NaCL apps.
All 5 of them?
No they won't, because NaCl is native x86. Unless you mean PNaCl, which is a different technology with much less adoption than NaCl.
So technically bother, then? NaCL programs are just as susceptible to buffer-overflow as conventional programs, its just they are better sandboxed. Exploit mitigation is a belt-and-braces thing, and I can't see why Google wouldn't be enabling this pass right now as we speak.
You have something compiled in NaCL like the Flash plugin and it can control the camera and stuff and you are hoping that an attacker can't feed it some malformed JPEG or something that makes it use the caps it has in a bad way etc.
Here's the only thread I could dig up on buffer overflows in NaCL: http://permalink.gmane.org/gmane.comp.security.nativeclient....
They might be able to apply that over all of android - and that will automatically apply over java based apps.From there it's just a matter of incentives, to rapidly create change in rest of the apps.
Now they already can, technically (via fat binaries, they've already been through multiple architectural transitions), the interesting part is they could now go through these transitions without developers having to be involved.
It also means the end of Universal binaries as Apple can thin the compiled app for each target device.
the PPC switch over was painful, as was the 32 versus 64 bit era. They want to avoid that in the future.
Here's a nice article describing it:
> This means that apps can automatically “take advantage of new processor capabilities we might be adding in the future, without you re-submitting to the store.”
http://thenextweb.com/apple/2015/06/17/apples-biggest-develo...
- Most real-world exploits these days are based on use-after-frees, heap buffer overflows, and other heap-related weirdness, rather than stack buffer overflows. It's nice that SafeStack mitigates that attack vector though (but if you disable stack canaries in favor of it, you actually reopen the door to exploit certain types of vulnerabilities...)
- A (the most?) common method to proceed from memory corruption to return-oriented programming is to redirect a virtual method call or other indirect jump to a stack pivot instruction. SafeStack alone does nothing to prevent this, so it doesn't prevent ROP.
- However, the general code-pointer indirection mechanisms described in the paper, of which SafeStack is an important component, could make ROP significantly harder, because you would only be able to jump to the starts of functions. This guarantee is similar to Windows's CFG (although the implementation is different), but SafeStack makes it harder to bypass by finding a pointer into the stack (either on the heap or via gadget).
- In practice, interoperation with unprotected OS libraries is likely to seriously compromise the security benefits of the combined scheme, because they will store pointers into the real stack, jump directly to code pointers on the heap, etc. JIT compilers are also likely to be problematic.
- In addition, there are more direct ways for an attacker to work around the protection, such as using as gadgets starts of functions that do some small operation and then proceed to a virtual call on an argument. The larger the application, the more possibilities for bypass there are.
- Still, "harder" is pretty good.
Edit: By the way, the point about function start gadgets makes questionable the paper's claim that "CPI guarantees the impossibility of any control-flow hijack attack based on memory corruptions." Also, if you want to guarantee rsp isn't leaked, it isn't enough to keep all pointers near it out of regular memory: they also have to be kept out of the stack itself, because functions with many (or variable) arguments will read them from the stack - at least, I don't see a claim in the paper about moving them - so subverting an indirect call to go to a function that takes more arguments than actually provided (or just changing a printf format string to have a lot of arguments) will cause whatever data's on the stack to be treated as arguments. Ditto registers that either can be used for arguments or are callee-saved. That means frame pointers have to be disabled or munged, and any cases where LLVM automatically generates temporary pointers for stack stores - which I've seen it do before - have to be addressed.
If you do move non-register arguments to the safe stack then the situation is improved, but you still have to watch out for temporaries left in argument registers.
int *p = cond ? &a : &b;
...later enough that this isn't trivially optimized into two stores...
*p = 1;
will probably not be flagged (it depends on what optimization passes have run before the SafeStack pass), but will put the pointer in the stack or a register that may be saved.