5 ms·
Hardening C/C++ Programs: Stack Protector
- alok-g 9y agoWould it have been better if the return addresses were put in a separate stack than the function variables to begin with?
- willvarfar 9y agoThis is what -fsanitize=safe-stack does in software https://clang.llvm.org/docs/SafeStack.html https://clang.llvm.org/docs/SafeStack.html and what the new Mill CPU does in hardware. On the Mill, the return addresses are on a hardware-managed call stack that cannot be corrupted by the program.
- titzer 9y agoIt's 2017 and we (still) have stack smashing bugs. I'm not really proud of what this says about our field.
- slededit 9y agoI really don't understand why we still mix our control and data stacks together. Memory fragmentation made this necessary in the past but we shouldn't need this anymore.
- AnimalMuppet 9y agoIt was convenient, when a function returned, to only have to pop one stack rather than two. And maybe more than just convenient. Mixing them allows stack smashing bugs, but it completely eliminates bugs where the control and data stacks get out of sync. Which is worse? We don't know, because we don't have decades of experience with "stack out of sync" attacks.
- slededit 9y agoAllowing a bug to hijack the control flow of the program is much worse. To a limited extent you can do this even with pure data manipulation (function pointers, if statement inputs etc) but it is much more constrained. FWIW Web Assembly doesn't mix the control and data stacks.
- titzer 9y agoCorrect. In fact, WebAssembly does not allow (indirectly) addressing the data stack at all. One must implement an addressable data stack in "userspace" with explicit management.
- beached_whale 9y agoNot all architectures do this, there are many systems with Hardvard Architecture in use
- slededit 9y agoHarvard architecture is separating the code address space from the data. But the stack itself intermingles return addresses "control" and data just the same.
- beached_whale 9y agoAh good point. But that would still mean the adversary has to put an address on the stack that already exists. Much harder target, no?
- slededit 9y agoYes but libc provides a juicy and consistent set of code you can jump to. Remember you don't have to jump to the start of a function. ASLR helps this a bit as well.
- beached_whale 9y agoI doubt libc(much of it like printf) or alsr exists on an 8051, maybe more so of libc on an AVR
- slededit 9y agoPowerPC is a harvard architecture. Its not just for small uCs.
- beached_whale 9y agoOoh, cool. I did not know of that one.
- ttd 9y agoAddressSanitizer is another approach to detect memory-related (including stack overflow) errors in C and C++ programs. See https://github.com/google/sanitizers/wiki/AddressSanitizer https://github.com/google/sanitizers/wiki/AddressSanitizer
- the_why_of_y 9y agoIn contrast to the stack protector described in the linked article, AddressSanitizer was designed as a debugging tool and is not suitable as a mitigation mechanism for production deployments.
- rurban 9y agoThis explanation would have been fine 5 years ago, but not even mentioning the superior -fstack-check or -fsanitize=cfi is criminal negligence.
- mrich 9y agoI will write about them, too. They are only implemented in clang. I'm using gcc for production builds so that's what I focused on first.
- Retr0spectrum 9y agoNote that enabling stack protection is often not enough to completely mitigate stack smashing attacks if there is a vulnerability in the code. For example if you can leak the value of the protector somehow, then you can just replace it with its original value when you smash the stack. Alternatively, it may be possible to brute-force the stack protector value, particularly on 32-bit systems where the protector often only has 24 bits of entropy.