Хорошие списки с объяснениями: [Links/Hardening]
Лично я бы всё свёл к:

* SSP: защита стэка канареечным значением, SafeStack, RETGUARD. Это
  требует только помощи компилятора. OpenBSD имеет патчи для GCC для
  SSP, но не остальных технологий. LLVM/Clang поддерживает всё
* Рандомизация адресного пространства (ASR, ALSR, RELRO, BIND_NOW, PIE,
  SEGVGUARD, размещение рандомное mmap-ed адресов, рандомизация символов
  и библиотек). Это требует и поддержки со стороны ОС/ядра, и некоторые
  вещи со стороны компилятора/линковщика (PIE). Поддерживается в
  OpenBSD, PaX патчах Linux, HardenedBSD (небольшой набор патчей для
  FreeBSD)
* NX, W^X: запрет существования исполняемых и записываемых страниц
  памяти. Может требовать изменения ПО (добавляя mprotect() вызовы) для
  W^X. Но для автоматической защиты стэка достаточно только поддержки со
  стороны ядра (что делается по сути всеми)

Другой защитой от *последствий* атак является privilege separation
(privsep) и privilege drop (privdrop) технологии:

* для setuid/setgid исполняемых файлов сразу же сбрасывать привилегии
  после запуска (set*id, setgroups)
* закрывать за собой все ненужные файлы
* делать chroot
* порождать процессы которые занимаются только своей одной какой-то
  частью: один только с сетью работает, другой с диском, третий с бизнес
  логикой, и т.д.. Общаются между собой по Unix-сокетам. Подход вовсю
  применяемый в OpenBSD и Postfix

privsep/privdrop из коробки имеет слишком большую гранулярность,
отвечает по сути только за операции с файлами. Можно использовать
capability-based security, где сама программа говорит как её надо
ограничить и что она вообще обещает и собирается использовать:

* pledge в OpenBSD позволяет чётко говорить что программа, после этого
  вызова, может делать: общаться только по stdio, читать файлы, делать
  на них stat, создавать временные файлы, chown/flock, dns, getpw,
  работать с сокетами, звуком, выставлять время, fork/exec, и т.д..
  Гранулярность хоть и довольно большая этих capabilities, но простота
  использования pledge легко позволит проект переводить на его
  использование (за пару недель сотни программ в OpenBSD переведены на
  использование pledge)
* unveil в OpenBSD похож на AppArmor и они позволяют per-filesystem-path
  задавать права доступа. По сути pledge это про группы системных
  вызовов, а unveil это как pledge для файлов на ФС
* FreeBSD имеет Capsicum. Она позволяет одним вызовом ограничить
  возможности по работе с глобальными объектами (файлы, PID-ы и прочее),
  оставляя возможность работы с локальными файловыми дескрипторами и
  shared memory. Файловые дескрипторы относятся не только к файлам
  файловой системы, но и сокетам, kqueue, открытым директориям,
  процессам (pdfork), pipe. Capsicum может задавать несколько десятков
  прав которые можно сделать с каждым из FD. Это намекает, в том числе,
  на использование privsep. В качестве примера имеется Casper библиотека
  с возможностью порождения процессов делающих DNS запросы, получающих
  рандом или getpw, к которым через Unix-сокет можно сделать RPC вызов.
  Для сериализации можно использовать libnv библиотеку (сериализация
  типизированных словарей) входящую в состав Capsicum. Не так просто как
  pledge, нет аналогичного инструмента типа unveil, но зато хорошая
  гранулярность. Но софт нужно писать with "privsep in mind"
* Linux имеет seccomp. Гораздо более сложную штуку чем всё описанное.
  Как и Capsicum она может одним вызовом оставить возможность только
  делать read/write/_exit/sigreturn вызовы (strict mode). А может
  использовать BPF-фильтр системных вызовов программы. Если в OpenBSD
  всё активно на pledge/unveil переведено, в FreeBSD десятки программ с
  каждым релизом переводятся на Capsicum, то seccomp массово не
  используется из-за сложности с его BPF.

Эти технологии приятны тем, что они вшиты в само ПО, не требуя ничего
более от пользователя/администратора. Имеют ничтожный overhead, о
котором можно не думать. Дружелюбны и намекают на использование
privsep/privdrop подхода.

Для ограничения ПО уже извне, а не полагаясь на то что программа будет
себя вести хорошо и корректно применять capability-based security,
используются:

* sandboxing технологии: jails (тут возможно и создание полностью
  отдельного своего сетевого стэка), cgroups, seccomp, chroot
* ACL для файлов: AppArmor, POSIX.1e (POSIX ACL) поддержка из коробки в
  большинстве GNU/Linux дистрибутивов и в FreeBSD, NFSv4 ACL (то, что
  заменило POSIX.1e) поддержка имеется только в ZFS, AIX, FreeBSD
* MAC (mandatory access control) технологии: SELinux, MAC подсистема
  FreeBSD (изначально появившаяся в TrustedBSD, реализующая POSIX.1e
  labels, Biba модель и другие)
* OpenBSD вообще ничего из вышеуказанного не имеет, кроме банального chroot

Так как некоторые операции требуют получения энтропии для эфемерных
ключей и векторов инициализации, то нужны права для /dev/urandom, что
либо делать через отдельный privsep-процесс, либо использовать не POSIX
функции типа getentropy (появилась в OpenBSD, позже в GNU/Linux и
FreeBSD), или arc4random. Современные реализации arc4random используют
ChaCha20, зерно которого взято честно из источника энтропии ОС, поэтому
это абсолютно безопасная замена /dev/urandom, не требующая работы с
файловой системой и файлами, никогда не падая.

Сделать в seccomp всё что делается в Capsicum -- можно, относительно
легко. Но в общем случае без рассмотрения исходного кода каждой
конкретной зависимости -- нельзя заранее понять и знать какие вызовы
будут использованы (делает ли PCSC библиотека poll, select или epoll?).
Кроме того, заранее неизвестно какие вызовы действительно будут
применяться даже libc -- например glibc при вызове waitpid() делает
wait4() на самом деле, а exit() вызывает exit_group(). То есть, seccomp
код, как минимум, даже с использованием libseccomp будет libc-specific
(даже от версии libc). И не исключено что в зависимости от платформы
libc может на деле использовать другие системные вызовы.

seccomp в итоге имеет самую маленькую гранулярность, возможность
регулировать каждый чих программы. Но он платформо/libc-специфичен и с
ним я потратил не один день на то, чтобы у меня в отдельном процессе
заработал PCSC код, общающийся с главным процессом. seccomp -- трудоёмко
использовать, как мне показалось. pledge имеет очень большую
гранулярность, но крайне низкий порог вхождения -- всё прямо
противоположного. Capsicum -- нечто среднее и заточенное на
использование файловых дескрипторов (которые в FreeBSD отвечают не
только за файловую систему, но и сокеты, mmap, процессы).

Не могу не отметить качество документации GNU/Linux: отвратительное.
Даже примеры из man-ов не работают и не могут даже в принципе:
указываются функции которых нет в заголовочных файлах. Поведение
(которое подглядываю в исходном коде glibc) не всегда соответствует тому
что написано в документации. Приходится регулярно смотреть в glibc/Linux
код. В BSD системах для работы с тем же kqueue или nvlist мне достаточно
было ровно одного man вызова, где содержится всё что нужно.