0

I have a program that mmaps memory at higher addresses using MAP_FIXED at TASK_SIZE - PAGE_SIZE.

This program runs fine if I execute it, but if I run it with gdb, it segfaults just after the mmap. Also at this point, the gdb state seems to be completely corrupted and it appears that the execution reaches an address range filled with 0's (could be from the new mappings just created).

Does gdb use this address range in the running process? Have I cleared out some of gdb's state? Is this address range documented somewhere?

Following is my call to mmap and the address calculation -

#define TASK_SIZE64 (0x800000000000UL - 4096)
#define TASK_SIZE TASK_SIZE64
#define PAGE_OFFSET (void*)TASK_SIZE
...
char *load_address = PAGE_OFFSET - file_size_aligned;
if(load_address != mmap(load_address, file_size_aligned, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)){
    err("Failed to allocate memory for raw_binary with: %d\n", errno);
    return -1;
}

file_size_aligned comes to a PAGE_SIZE. This is one of the allocations. There is one more that starts from load_address and allocates few more pages backwards (with PROT_READ and PROT_WRITE only).

Ajay Brahmakshatriya
  • 8,993
  • 3
  • 26
  • 49
  • Check this answer: https://stackoverflow.com/questions/3640095/gdb-cant-access-mmapd-kernel-allocated-memory. It looks like you need to create function within your program that gives GDB access to those memory regions if you want to inspect them. – Paul Nov 25 '18 at 08:48
  • @Paul I don't think that question is exactly related. I am not mmap'ing the memory in the kernel space. It is inside the user space - `TASK_SIZE - PAGE_SIZE`. This memory should be accessible by gdb if it needs to. – Ajay Brahmakshatriya Nov 25 '18 at 08:52
  • Ah, good point. Can you include the call you are making to `mmap`? Are you getting an address back from mmap, or you are requesting one? – Paul Nov 25 '18 at 08:57
  • @Paul I am using `MAP_FIXED` -- I am passing my own address. Will add the call to mmap. – Ajay Brahmakshatriya Nov 25 '18 at 09:11
  • Does it work if you remove the MAP_FIXED argument? It would be good to know if using GDB with that address space is the cause rather than a GDB issue in general. – Paul Nov 25 '18 at 09:29
  • For example, this code works fine for me, running with or without GDB. I can't map that exact address you use in my setup, so I chose another that will work: `int main(int argc, char const *argv[]) { char *load_address = (void*) 0x7fffff7c0000; void* ret = mmap(load_address, file_size_aligned, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); printf("%d, %p, %p\n", errno, ret, load_address); return 0; }` – Paul Nov 25 '18 at 09:34
  • @Paul I think it is the issue with the address range, so it works in your case. And I kind of need this address range. I can another address range to see if it makes gdb work, but I have to eventually get this address range. – Ajay Brahmakshatriya Nov 25 '18 at 09:41

1 Answers1

1

Does gdb use this address range in the running process?

No.

Have I cleared out some of gdb's state?

No.

Is this address range documented somewhere?

Possibly in kernel sources.

Your program makes invalid assumptions about available address space, and "blows itself up" when run with ASLR turned off (which GDB does by default).

You can confirm this by running your program outside GDB, but with ASLR disabled. It should also crash. Try one of these:

# echo 0 > /proc/sys/kernel/randomize_va_space

or

setarch $(uname -m) -R /path/to/exe

You can also confirm that your program will run under GDB if you enable ASLR:

gdb /path/to/exe
(gdb) set disable-randomization off
(gdb) run
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Alright, this makes a lot more sense. I actually have to acquire an address range according to some other constraints too. So I am trying not to use `mmap(NULL, ...)`. The address range I had used satisfied the other constraint. I thought this would be free for most processes too. Didn't realize with ASRL turned off, the mapping starts right from the bottom. – Ajay Brahmakshatriya Nov 25 '18 at 19:34