1

Why do I get a segmentation fault?

I'm using nasm -f elf64 t.asm -o t.o ld t.o -o t to compile on linux.

I've done all I can think of.

section .data:
  variable_int db 1
  variable_string db "yaaaa", 10
section .text:
  global _start
_start:
  mov rax, 1
  mov rdi, 1
  mov rsi, variable_string
  mov rdx, 14
  syscall
  mov rax, 60
  mov rdi, 0
  syscall
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    I don't get a segfault when I try running your program but your length param for the `write` syscall is larger than the length of the string at `variable_string`. – mediocrevegetable1 Sep 20 '21 at 04:13
  • If it doesn't segfault, it's probably due to an older system where READ_IMPLIES_EXEC ends up on by default for asm programs. In more recent systems, you'll "just" get an executable stack, so code in random section names (not `.text`) won't be in executable pages. [Unexpected exec permission from mmap when assembly files included in the project](https://stackoverflow.com/q/58260465) / [Linux default behavior of executable .data section changed between 5.4 and 5.9?](https://stackoverflow.com/q/64833715) – Peter Cordes Sep 12 '22 at 05:41

1 Answers1

6
section .data:
section .text:

Omit the colons. A section directive is not a label, and the colon is parsed as part of the section name. This causes your data to be put in a section called .data: whereas the linker is expecting a section called .data without the colon. This may cause the section to be given the wrong permissions (e.g. a .text: section which is not executable).

Also:

mov rdx, 14

This parameter is the length of the data to be written, and your string is not 14 bytes long; it is only 6. This may result in extra garbage being written (which may or may not be visible characters) or potentially a failure of the system call if this runs into unmapped memory.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • 2
    Fun fact: On current Linux, a length that runs into an unmapped page doesn't return -EFAULT unless where were 0 valid bytes. It writes the bytes up to the unmapped page and returns the number of bytes it could copy. (I forget if I've tested with really tiny buffers like this near the end of a page; I have tested with a ~4k size starting near the start of a page.) – Peter Cordes Sep 20 '21 at 09:16