Skip to content
Advertisement

trying to cause SIGSEGV in mmap

I’m trying to create a memory mapping of length greater than the underlying file. When I access pages of the mapping (which are not correspondingly mapped to a file), a SIGBUS is caused. However when I try to access the memory outside the memory mapping length, it should cause SIGSEGV (but isn’t), why is that?

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char* argv[]) {

  char* inp_file_name = argv[1];
  int src_fd = open(inp_file_name, O_RDWR);

  printf("system page size is: %ldn", sysconf(_SC_PAGE_SIZE));
  struct stat buf;
  fstat(src_fd, &buf) == -1);

  printf("file size is: %ldn", buf.st_size);

  // create a larger mmap
  // file size is 9360bytes,
  // generated by: dd if=/dev/random of=rand_inp count=120
  char* addr = mmap(NULL, 2 * buf.st_size, PROT_READ, MAP_PRIVATE, src_fd, 0);

  // SIGBUS
  //  printf("value at point in unmapped file region: %c", addr[13000]);

  // SIGSEGV
  // this doesn't happen, probably because we're accessing process virtual memory
  // which is not inaccessible
  printf("value at point in unmapped file region: %c", addr[40000]);
}

Advertisement

Answer

Stopping your program and dumping /proc/pid/maps just after the mmap call, I get

563e4afb3000-563e4afb4000 r-xp 00001000 00:2a 1668                       /tmp/a.out
563e4afb4000-563e4afb5000 r--p 00002000 00:2a 1668                       /tmp/a.out
563e4afb5000-563e4afb6000 r--p 00002000 00:2a 1668                       /tmp/a.out
563e4afb6000-563e4afb7000 rw-p 00003000 00:2a 1668                       /tmp/a.out
563e4b9bb000-563e4b9dc000 rw-p 00000000 00:00 0                          [heap]
7f3fa121b000-7f3fa121e000 rw-p 00000000 00:00 0 
7f3fa121e000-7f3fa1246000 r--p 00000000 00:1c 8098578                    /usr/lib/x86_64-linux-gnu/libc.so.6
7f3fa1246000-7f3fa13db000 r-xp 00028000 00:1c 8098578                    /usr/lib/x86_64-linux-gnu/libc.so.6
7f3fa13db000-7f3fa1433000 r--p 001bd000 00:1c 8098578                    /usr/lib/x86_64-linux-gnu/libc.so.6
7f3fa1433000-7f3fa1437000 r--p 00214000 00:1c 8098578                    /usr/lib/x86_64-linux-gnu/libc.so.6
7f3fa1437000-7f3fa1439000 rw-p 00218000 00:1c 8098578                    /usr/lib/x86_64-linux-gnu/libc.so.6
7f3fa1439000-7f3fa1446000 rw-p 00000000 00:00 0 
7f3fa145f000-7f3fa1464000 r--p 00000000 00:2a 1657                       /tmp/foo
7f3fa1464000-7f3fa1466000 rw-p 00000000 00:00 0 
7f3fa1466000-7f3fa1468000 r--p 00000000 00:1c 8098572                    /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f3fa1468000-7f3fa1492000 r-xp 00002000 00:1c 8098572                    /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f3fa1492000-7f3fa149d000 r--p 0002c000 00:1c 8098572                    /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f3fa149e000-7f3fa14a0000 r--p 00037000 00:1c 8098572                    /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f3fa14a0000-7f3fa14a2000 rw-p 00039000 00:1c 8098572                    /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7fff213d8000-7fff213f9000 rw-p 00000000 00:00 0                          [stack]
7fff213fa000-7fff213fe000 r--p 00000000 00:00 0                          [vvar]
7fff213fe000-7fff21400000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]

So there are several other mappings immediately following the mapping of the file foo. I think your byte is at address 0x7f3fa1468c40 which is in one of the mappings of /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so, the dynamic linker. It’s readable mapped memory, whose contents happen not to be meaningful to you.

It looks from this like Linux’s memory mapping algorithm is to grow downwards, with each mapping placed in virtual memory just below the previous one. So it’s not surprising that when you go a short ways beyond your mapping, you end up at an address that is part of another map.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement