- Memory-safe languages where possible.
- Sandboxing of applications, parsers, etc., along with a strong permission model.
- Mitigation like secure app spawning, zeroing out pages, etc.
- Modern mitigation hardware-assisted mitigation like MTE and PAC.
- Storing secrets in a separate secure enclave (not ~/.config or ~/.ssh).
- Read-only and fully verified system partitions (anti-persistence).
This graph:
https://security.apple.com/assets/image/generated/xlarge_adv...
from Apple's MIE docs [1] shows where modern systems like iOS and Android are. An attacker often needs a long exploit chain to compromise a device and it becomes increasingly difficult with various mitigation techniques. On the standard Linux desktop it's often as easy as exploiting an image parser in a client. Old parsers in C have a history of bad vulnerabilities, exploiting one often gives you privileges of the process calling the function, since Linux applications mostly don't separate/sandbox parsers and from there you have direct access to all data of the user, since Linux applications are typically not sandboxed.
[1] https://security.apple.com/blog/memory-integrity-enforcement...