Let us say I have a large C++ codebase which I am unwilling to rewrite in Rust. But I:
* Enable STL bounds checking using appropriate flags (like `-DGLIBCXX_ASSERTIONS`).
* Enable mitigations like CFI and shadow stacks.
How much less safe is "C++ w/ mitigations" than Rust? How much of the "70% CVE" statistic is relevant to my codebase?
https://securitycryptographywhatever.com/2024/10/15/a-little...
* CFI
* isoheaps or type-stable allocators
* Shadow stacks
(There is just a single hit of "C++"...)
Ignoring the appeal to authority, I have a hard time believing that incrementally rewriting my C++ code in Rust or just writing new code in Rust ("vulnerabilities exponentially decay" and all that) is going to give me more actual security than the mitigations stated above. Most, if not all, high-profile exploits stem from out-of-bounds accesses and type confusions, which these mitigations prevent at very low cost.
Thanks for replying, though.
> They prevent but do not entirely mitigate.
Ignoring the semantic difference between "prevent" and "mitigate", if at the end of the day, the security provided by the two different approaches are quite similar, I don't get the problem.
If you have an example of a successful widespread exploit that would have happened even with these mitigations, please share.
Note that I am not very knowledgeable in security, and I am really willing to be educated but it feels like most of the replies to my comments are just trying to prove me wrong.
I can't really speak to your comments as you haven't posted many of them. I'm not here to prove you wrong but just to share my views on these mitigations. I'm not an expert by any means but I do get to think about these for work so I can usually do at least a quick once-over to try to figure out how effective they might be.
> Overwriting function pointers gives code execution under shadow stacks
As you are probably aware, there are two kinds of CFI - forward-edge and backward-edge. Forward-edge CFI prevents tampered function pointers, vtables and such from being invoked. Whereas backward-edge CFI protects does the same for return addresses. Clang's and MSVC's (CFG) implementations of CFI only provide forward-edge protection, hence the need for shadow stacks. Without hardware support, shadow stacks can not be prevented from tampered, which is why Intel (CET) and AMD added shadow stacks.
> Mobile platforms are very memory sensitive
Agreed. I'd guess this applies to embedded too. But all things considered, I do hold the opinion that language-level memory safety is being overplayed a lot.