linux - ¿Por qué los segmentos de pila y datos son ejecutables?
assembly nasm (1)
En los sistemas Linux modernos, el enlazador marcará IFF no ejecutable de pila / datos. Todos los objetos que participan en el enlace tienen una sección especial "marcador" .note.GNU-stack
.
Si compila, por ejemplo, int foo() { return 1; }
int foo() { return 1; }
en ensamblaje (con gcc -S foo.c
), verá esto:
.section .note.GNU-stack,"",@progbits
Para nasm
, la sintaxis se muestra en la sección 7.9.2 del manual ; quieres algo como esto:
section .note.GNU-stack noalloc noexec nowrite progbits
Nota
Esto tiene que hacerse para cada archivo .o
que vaya al ejecutable. Si algún archivo de objeto necesita pila o datos ejecutables, se configura para todo el segmento.
Me acabo de dar cuenta de que mi programa simple tiene sus segmentos de datos y pila ejecutables. Lo vi en / proc / [pid] / maps, y el código simple lo confirmó.
Por ejemplo:
; prog.asm
section .data
code: db 0xCC ;int3
section .text
global _start
_start:
jmp code
mov rax, 60 ; sys_exit
mov rdi, 0
syscall
entonces
nasm -f elf64 prog.asm
ld -o prog prog.o
./prog
hace que prog ejecute la instrucción int3.
Los programas escritos en C y construidos con gcc tienen sus datos, stack y heap no ejecutables, entonces ¿por qué aquellos escritos en ensamble se comportan de manera diferente?