Я провожу некоторые эксперименты со стеком, и следующее застряло.
Видно, что Linux имеет начальное [stack]
отображение 132KiB
в размере. В случае ulimit -s unlimited
мы можем расширить стек дальше, если настроим rsp
соответственно. Поэтому я установил ulimit -s unlimited
и запустил следующую программу:
PAGE_SIZE equ 0x1000
;mmap staff
PROT_READ equ 0x01
PROT_WRITE equ 0x02
MAP_ANONYMOUS equ 0x20
MAP_PRIVATE equ 0x02
MAP_FIXED equ 0x10
;syscall numbers
SYS_mmap equ 0x09
SYS_exit equ 0x3c
section .text
global _start
_start:
; page alignment
and rsp, -0x1000
; call mmap 0x101 pages below the rsp with fixed mapping
mov rax, SYS_mmap
lea rdi, [rsp - 0x101 * PAGE_SIZE]
mov rsi, PAGE_SIZE
mov rdx, PROT_READ | PROT_WRITE
mov r10, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED
mov r8, -1
mov r9, 0
syscall
sub rsp, 0x80 * PAGE_SIZE
mov qword [rsp], -1 ; SEGV
mov rax, SYS_exit
mov rdi, 0
syscall
Даже несмотря на то, что rsp
настроен, он в любом случае вызывает ошибку. Я не совсем понял суть. Я вручную создал фиксированное отображение по адресу rsp - 0x101 * PAGE_SIZE
101 страниц ниже rsp
.
Я ожидал, что это не помешает расширению стека (rsp - 0x80
в моем случае), пока мы не достигнем фиксированного отображения rsp - 0x101 * PAGE_SIZE
.
Кстати, если я удаляю MAP_FIXED
из сопоставления, это не учитывается и не происходит никакого сбоя (как и ожидалось). Вот результат вывода:
mmap(0x7ffe4e0fe000, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x1526e3f3a000
Но MAP_FIXED
делает работу:
mmap(0x7ffd8979c000, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffd8979c000
UPD: segfault не срабатывает, если lea rdi, [rsp - 0x101 * PAGE_SIZE]
заменяется на lea rdi, [rsp - 0x200 * PAGE_SIZE]
.