Paul Eggert wrote: > > On Linux, the kernel allows the stack to grow by any amount, if it does not > > become closer than 1 MB to another VMA and does not violate the set limits. > > See linux/mm/mmap.c:expand_downwards and linux/mm/mmap.c:acct_stack_growth. > > Therefore on Linux, there is no need for a guard page and no need for > > 'gcc -fstack-clash-protection'. > > There's still a need, if a function declares a large local variable, as the > stack pointer can jump around the 1 MB barrier and trash other storage. If I > compile the attached program with 'gcc -m32 -O2 stackish.c' on Fedora 31 > x86-64, > the program exits with status 255 (instead of crashing with a stack overflow > as > it should), because the stack has overflowed and has stomped on the heap. So > stack overflow checking is not "just working", at least for this particular > case.
Oh, I see: your program is not getting near the heap with the stack, it is getting directly *into* the heap (because it fills the bottom of array 'b' without having filled the rest of 'b' first). gcc -fstack-clash-protection -m32 -O2 stackish.c fixes this issue. So, you want 'gcc -fstack-clash-protection' [1] to become enabled by default? Some distros are doing this already: - Ubuntu 20.04 [2] (also -fstack-clash-protection is part of the default gcc flags for users), - RHEL 8 [1] (but apparently not by default for user-compiled programs), and the Firefox people are considering it [3]. Bruno [1] https://developers.redhat.com/blog/2020/05/22/stack-clash-mitigation-in-gcc-part-3/ [2] https://lists.ubuntu.com/archives/ubuntu-devel/2019-June/040741.html [3] https://bugzilla.mozilla.org/show_bug.cgi?id=1588710
.file "stackish.c" .text .p2align 4 .globl growby .type growby, @function growby: .LFB27: .cfi_startproc endbr64 pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movslq %edi, %rdi addq $15, %rdi movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp movq %fs:40, %rax movq %rax, -8(%rbp) xorl %eax, %eax movq %rsp, %rdx movq %rdi, %rax andq $-4096, %rdi subq %rdi, %rdx andq $-16, %rax cmpq %rdx, %rsp je .L3 .L14: subq $4096, %rsp orq $0, 4088(%rsp) cmpq %rdx, %rsp jne .L14 .L3: andl $4095, %eax subq %rax, %rsp testq %rax, %rax jne .L15 .L4: movl %esi, %r8d movq %rsp, %rcx addl $256, %r8d js .L5 movl %r8d, %edi xorl %eax, %eax .p2align 4,,10 .p2align 3 .L6: movq %rax, %rdx movb %al, (%rcx,%rax) addq $1, %rax cmpq %rdx, %rdi jne .L6 .L5: movslq %esi, %rsi movslq %r8d, %r8 movsbl (%rcx,%rsi), %eax movsbl (%rcx,%r8), %edx subl %edx, %eax movq -8(%rbp), %rsi xorq %fs:40, %rsi jne .L16 leave .cfi_remember_state .cfi_def_cfa 7, 8 ret .p2align 4,,10 .p2align 3 .L15: .cfi_restore_state orq $0, -8(%rsp,%rax) jmp .L4 .L16: call __stack_chk_fail@PLT .cfi_endproc .LFE27: .size growby, .-growby .section .text.startup,"ax",@progbits .p2align 4 .globl main .type main, @function main: .LFB28: .cfi_startproc endbr64 pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movl $1, %esi movq %rsp, %rbp .cfi_def_cfa_register 6 pushq %r12 .cfi_offset 12, -24 leal 1073741824(%rdi), %r12d pushq %rbx .cfi_offset 3, -32 movl %edi, %ebx movslq %r12d, %rdi subq $16, %rsp movq %fs:40, %rax movq %rax, -24(%rbp) xorl %eax, %eax call calloc@PLT movl %r12d, %edx movq %rsp, %rdi shrl $31, %edx movq %rax, %rcx movq %rax, -32(%rbp) leaq -32(%rbp), %rax addl %r12d, %edx sarl %edx movslq %edx, %rdx addq %rcx, %rdx movq %rsp, %rcx subq %rdx, %rax cltq addq $15, %rax movq %rax, %rdx andq $-4096, %rax subq %rax, %rcx andq $-16, %rdx movq %rcx, %rax cmpq %rax, %rsp je .L19 .L32: subq $4096, %rsp orq $0, 4088(%rsp) cmpq %rax, %rsp jne .L32 .L19: andl $4095, %edx subq %rdx, %rsp testq %rdx, %rdx jne .L33 .L20: movl %ebx, %r8d movq %rsp, %rcx addl $256, %r8d js .L21 movl %r8d, %esi xorl %eax, %eax .p2align 4,,10 .p2align 3 .L22: movq %rax, %rdx movb %al, (%rcx,%rax) addq $1, %rax cmpq %rdx, %rsi jne .L22 .L21: movslq %ebx, %rax movslq %r8d, %r8 movsbl (%rcx,%rax), %eax movsbl (%rcx,%r8), %edx movq %rdi, %rsp subl %edx, %eax testl %r12d, %r12d jle .L17 leal 1073741823(%rbx), %r8d xorl %ecx, %ecx .p2align 4,,10 .p2align 3 .L24: movq -32(%rbp), %rsi addq %rcx, %rsi movsbl (%rsi), %edx leal 1(%rdx), %edi orl %edx, %eax movq %rcx, %rdx addq $1, %rcx movb %dil, (%rsi) cmpq %rdx, %r8 jne .L24 .L17: movq -24(%rbp), %rbx xorq %fs:40, %rbx jne .L34 leaq -16(%rbp), %rsp popq %rbx popq %r12 popq %rbp .cfi_remember_state .cfi_def_cfa 7, 8 ret .L33: .cfi_restore_state orq $0, -8(%rsp,%rdx) jmp .L20 .L34: call __stack_chk_fail@PLT .cfi_endproc .LFE28: .size main, .-main .ident "GCC: (Ubuntu 9.3.0-10ubuntu2) 9.3.0" .section .note.GNU-stack,"",@progbits .section .note.gnu.property,"a" .align 8 .long 1f - 0f .long 4f - 1f .long 5 0: .string "GNU" 1: .align 8 .long 0xc0000002 .long 3f - 2f 2: .long 0x3 3: .align 8 4: