0

x86-64 System V ABIでは、の後ろのスペース$rsp - 128は、シグナル ハンドラが触れない、いわゆるレッド ゾーンであると指定されています。私のマシンで

$ ulimit -s
8192

スタックには 2 ページしかないと予想していました。そこで、次のプログラムを作成して、どのサイズのレッド ゾーンが拡大できるかをテストしました。

PAGE_SIZE equ 0x1000
SYS_exit equ 0x3C

section .text
global _start 

_start:
    lea rcx, [rsp - 0x1f * PAGE_SIZE]
    mov rax, rsp
loop:
    sub rax, PAGE_SIZE
    mov qword [rax], -1
    cmp rax, rcx
    jne loop

    mov rax, SYS_exit
    mov rdi, 0x20

したがって、プログラムは常に失敗すると予想していました。しかし、プログラムは で失敗することもあればSEGV、正常に終了することもあります。

MAP_GROWSDOWN動作は、次のドキュメントとまったく同じです。

このフラグはスタックに使用されます。これは、カーネル仮想メモリ システムに対して、マッピングがメモリ内で下位に拡張する必要があることを示します。戻りアドレスは、プロセスの仮想アドレス空間で実際に作成されるメモリ領域よりも 1 ページ下になります。マッピングの下にある「ガード」ページのアドレスに触れると、マッピングが 1 ページ分大きくなります。この成長は、マッピングが次に低いマッピングの上限のページ内に成長するまで繰り返すことができ、その時点で「ガード」ページに触れるとSIGSEGV信号が発生します。

この質問で説明したように、作成されたマッピングはそのようには成長MAP_GROWSDOWNPROT_GROWSDOWNません。

volatile char *mapped_ptr = mmap(NULL, 4096,
                        PROT_READ | PROT_WRITE | PROT_GROWSDOWN,
                        MAP_GROWSDOWN | MAP_ANONYMOUS | MAP_PRIVATE,
                        -1, 0); 

mapped_ptr[4095] = 'a';  //OK!
mapped_ptr[0]    = 'b';  //OK!
mapped_ptr[-1]   = 'c';  //SEGV

質問:上記の理由を組み合わせると、使用する唯一のマッピングがMAP_GROWSDOWNメイン スレッドの[stack]マッピングであるというのは本当ですか?

4

2 に答える 2