Каждый поток имеет стек. Стек — это особая область памяти, используемая потоком для хранения локальных переменных. адрес возврата функции и т. д. Когда ЦП выполняет поток, его регистр (SP )должен указывать на адрес памяти со стеком.
В большинстве случаев ядро выделяет стек потока, но иногда стеки создаются приложением :Приложения могут создавать собственный стек для кода обработчиков сигналов (, который выполняется, когда ядро отправляет сигнал процессу ). или они могут сделать это для реализации библиотеки потоков.
Для этого приложение запрашивает у ядра область памяти, а затем помечает ее как стек, чтобы ядро знало, что эта область является стеком. Но из-за ошибок разработчиков приложение может запросить у ядра часть памяти для стека, которая не была зарегистрирована для него. тот. В этом случае может произойти что-то плохое :ядро может перезаписать полезные данные, потому что думает, что пишет в стек, но оно это не стек! Хакеры могут использовать его для взлома программ.
В OpenBSD, когда вы резервируете память (с помощью mmap, например ), вы должны ЯВНО сказать, что:
Сценарий солнечного дня:
Сценарий дождливого дня:
Вот еще несколько примеров таких флагов:
PROT _EXEC :просит ядро зарезервировать память для хранения кода (что-то, что ЦП может выполнить )PROT _WRITE :просит ядро зарезервировать память для записываемых данных
Таким образом, вы не можете выполнить свои данные или записать в свой код (это называется W^X и люди OpenBSD гордятся этим)
Вы можете прочитать man mmap
и map sigaltstack
для получения дополнительных примеров