7

Stack layout is well documented in many ways. Especially for x86 systems as there were numerous tutorials on how to exploit stack overflow on old 32-bit systems many years ago.

So far we can know that on a 32-bit system, the user stack starts from 0xc0000000 address (which is the limit between usermode and kernelmode).

This address is not the same if we take an Elf32 running on a x86-64 linux system.

I cannot find this address but I can figure out it is 0xffffe000 thanks to gdb:

(gdb) x $esp 0xffffd4bc: 0xf7e16a83 (gdb) x/w 0xffffdffc 0xffffdffc: 0x00000000 (gdb) x/w 0xffffe000 0xffffe000: Cannot access memory at address 0xffffe000

We can actually see that the 0xffffe000 address points to an invalid location (or at least the process doesn't have proper permission to access this memory page).

Yet I cannot especially find a relevant source that tells us that the gnu stack of a x86 program on a x64 linux starts from 0xffffe000. Am I doing things wrong?

I can find sources telling us about linux-gate.so.1 but I do not think this is the point here.

Any ideas, reversers?

5

2 Answers 2

2

The valid stack access range of a (32 or 64 bit) process can be viewed by looking into its memory map. We can observe the memory map of a process with id pid by cat /proc/pid/maps, an example of a 32-bit process on my 64-bit box:

...
09b58000-09b79000 rw-p 00000000 00:00 0                    [heap]
...
f7785000-f7787000 rw-p 001c7000 00:23 592106               /usr/lib/libc-2.20.so
...
f77c2000-f77c4000 r--p 00000000 00:00 0                    [vvar]
f77c4000-f77c5000 r-xp 00000000 00:00 0                    [vdso]
...
f77e8000-f77e9000 rw-p 00022000 00:23 592099               /usr/lib/ld-2.20.so
fff9b000-fffbc000 rw-p 00000000 00:00 0                    [stack]

Then the valid range for stack is [0xfff9b000, 0xfffbc000), memory access to an address higher or equal than 0xfffbc000 will trigger memory access violation exception. According to this article, this range is calculated when the kernel maps the binary into the memory, and by several functions, the interesting input for them is STACK_TOP which is defined by TASK_SIZE for 32-bit processes.

2
  • Well, I guess this deserves several further investigations. Thanks for your answer. Apr 12, 2016 at 14:28
  • Thanks @GeoffreyR., you are welcome. In fact, I have the same question with you. Apr 12, 2016 at 14:32
0

I have a partial answer.

One can determine wether the memory layout ends up to 0xc0000000 or 0xffffe000 thanks to the personality system call. By reading the ADDR_LIMIT_3GB flag it is possible to figure out wether a 32-bit process is mapped up to 0xc0000000 or 0xffffe000.

I could not tell why the 0xffffe000 is relevant, except that it is 8192 bytes shorter that the end of a 4GB memory space. Maybe it has something to do with the kernel stack size.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.