On Wed, Apr 20, 2016 at 06:09:54PM +0200, Volodymyr Kuznetsov wrote: > On Wed, Apr 20, 2016 at 4:54 PM, Szabolcs Nagy <szabolcs.n...@arm.com> wrote: > > On 13/04/16 14:01, Cristina Georgiana Opriceana wrote: > >> I bring to your attention SafeStack, part of a bigger research project > >> - CPI/CPS [1], which offers complete protection against stack-based > >> control flow hijacks. > > > > i think it does not provide complete protection. > > > > it cannot instrument the c runtime or dsos and attacks > > can be retried on a forking server which has fixed memory > > layout, so there is still significant attack surface. > > > > (it would be nice if security experts made such claims > > much more carefully). > > OK, the point is well taken, every actual implementation of such > techniques is bound to have limitations like the ones you mention. The > protection can only be complete in an academic sense: assuming the > perfect implementation that follows the CPI formal model, has perfect > safe region isolation, etc. In practice, we're just trying to make the > attacker's job harder. > > > > >> In GCC, we propose a design composed of an instrumentation module > >> (implemented as a GIMPLE pass) and a runtime library. > > ... > >> The runtime support will have to deal with unsafe stack allocation - a > >> hook in the pthread create/destroy functions to create per-thread > >> stack regions. This runtime support might be reused from the Clang > >> implementation. > > > > the SafeStack runtime in compiler-rt has various issues > > that should be clearly documented. > > Thanks a lot for pointing it out, getting such feedback is one of the > reasons we want to upstream this in the first place. The other reasons > include getting more people to use and to improve the code by fixing > such issues. > > > > > it seems the runtime > > > > * aborts the process on allocation failure. > > > > * deallocates the unsafe stack using tsd dtors, but > > signal handlers may run between dtors and the actual > > thread exit.. without a mapped unsafe stack. > > I think the only correct way to handle this is to put the unsafe stack > allocation/deallocation code into libc. We implemented it for FreeBSD > libc in a way that imposes no overhead for apps that don't use > safestack, perhaps something similar could be possible in glibc. We'd > welcome any better suggestions on this!
There's a trivial solution that has no allocation/deallocation complexities: __thread char __unsafestack[LARGEVALUE]; However I think a better alternative might be to use the system (for main thread) or libc-provided (for other threads) stack as the unsafe stack, and move the main stack pointer to point at a secondary safe stack, which could then be: __thread char __safestack[MEDIUMVALUE]; Since the unsafe stack is where large buffers can live, and the safe stack is basically just register spills/return addresses, the safe stack could reasonably be a fairly small, fixed size. > > * determines the main stack with broken heuristic > > (since the rlimit can change at runtime i don't think > > this is possible to do correctly in general). > > > > * interposes pthread_create but not c11 thrd_create > > so conforming c11 code will crash. (same for non-standard > > usage of raw clone.) > > > > * sigaltstack and swapcontext are broken too. > > We have prototype that supports swapcontext that we're happy to > release, but it clearly requires more work before being ready to merge > upstream. The *context APIs are deprecated and I'm not sure they're worth supporting with this. It would be a good excuse to get people to stop using them. > > > problems than the compiler parts: it has to be reliable > > and abi stable since safestack is advertised for > > production use. > > > > (i think gcc should raise the bar for runtime code > > quality higher than that, but there is precedent Agreed. > > for much worse runtimes in gcc so this should not > > block the safestack porting work, however consider > > these issues when communicating about it to upstream > > or to potential users.) Also agree. Rich