Search code examples
linuxsegmentation-faultx86-64nasmmmap

How to use value on address acquired from mmap?


having this nasm:

%define O_RDONLY 0
%define PROT_READ 0x1
%define MAP_PRIVATE 0x2

section .data
fname: db 'test.txt', 0

section .text
global _start
print:
 ; ---- THIS PART ADDED
    mov r15, [rdi]
    add r15, 1 ; have tried `inc byte[rdi]` - did not work either
    mov [rdi], r15
 ; ---- END OF ADDED PART
 ; else is according to book (so correct)
    push rdi


    call str_len
    pop rsi
    mov rdx, rax
    mov rax, 1
    mov rdi, 1
    syscall
    ret
str_len:
    xor rax, rax
.loop:
    cmp byte [rdi+rax], 0
    je .end
    inc rax
    jmp .loop
.end:
    ret

_start:
    ;call open
    mov rax, 2
    mov rdi, fname
    mov rsi, O_RDONLY 
    mov rdx, 0 
    syscall

    ;mmap
    mov r8, rax 
    mov rax, 9 
    mov rdi, 0 
    mov rsi, 4094 
    mov rdx, PROT_READ 
    mov r10, MAP_PRIVATE  
    mov r9, 0 
    syscall

    mov rdi, rax ;returned address 
    call print
    mov rax, 60
    xor rdi, rdi
    syscall

The file test.txt contains only one char at the beginning - 5.

I got address from region asked by mmap in rax, which I then move to rdi. And I simply want to increment the value (at that address - now being in rdi):

    mov r15, [rdi]
    add r15, 1 ; have tried `inc byte[rdi]` - did not work either
    mov [rdi], r15
    push rdi

So i temporary move the value on r15, the increment it (add it 1), and try to move it back to address of that region (address still in rdi). But then segfault.

Why is that? Why cannot I use the value on the address (to the acquired region from mmap), which contain 5 - one byte (on which the rdi points), and use it in arithmetic?

If that would be address declared in data segment, then there would be no problem (I have tried). But the address is from mmap, So how does it differ, and how to fix that?


Solution

  • Writing to read-only memory segfaults (mov [rdi], r15 qword store, or inc byte [rdi] byte RMW).

    You need PROT_READ | PROT_WRITE if you want to be able to write as well as read.

    (Note that writing to a MAP_PRIVATE mapping triggers a copy-on-write, leaving you with a private page that's no longer backed by the file, just like if you'd done a read into a MAP_ANONYMOUS page.)