Smashing Stack on Ubuntu 11.10
segmentation-fault, stack, ubuntu, x86
Solution
This is related to the implementation of NX emulation in the 32-bit non-PAE Ubuntu kernels, and when the CPU exception is raised. For memory regions below the NX emulation line (i.e. "within" the emulated NX area: from address 0 to the end of the program's text segment -- less than the 0x08049000 end-address of this binary in `/proc/$pid/maps`), the segfault is delivered after EIP has landed on the actual invalid address. For addresses above the line, the fault gets triggered through a different path that reports the failure without moving EIP forward to faulting address, staying instead on the "ret" instruction that leads to the fault.
You can see this in gdb:
(gdb) x/1i $pc
=> 0x8048454 <main+64>: ret
(gdb) info reg esp
esp 0xbffff54c 0xbffff54c
(gdb) x/wx $esp
0xbffff54c: 0x41414141
You can also see the difference in how the faults are reported in `dmesg` output. This is the output associated with the "508" attempt:
[ 585.913896] a.out[1528] general protection ip:8048454 sp:bff1e8ec error:0 in a.out[8048000+1000]
And this is for "507":
[ 598.999760] a.out[1531]: segfault at 414141 ip 00414141 sp bfcac2c0 error 4 in libc-2.13.so[5e7000+178000]
If you boot with the PAE kernel installed, `sudo apt-get install linux-image-$(uname -r)-pae`, and you have a PAE capable CPU, you'll see the behavior you'd expect (since NX emulation will be disabled in favor of hardware NX), and all 4 attempts will segfault with the expected EIPs.
Problem
Did any of you face the following problem when you try to overwrite the `$esp` pointer? Of course trying a legit buffer size always works! But, when you try to increase the buffer size to overwrite the `$esp` and you manage to success to touch the first byte, second byte, or third byte of `$esp` it works perfectly. But, as soon as you try to overwrite the whole 4 bytes of the `$esp` it totally changes the content of it as well as the address. It doesn't show `41`s any more as I used "A"s to fill the buffer. I've attached a screen shot maybe it will explain in more details. Thanks all. ``` #include <stdio.h> #include <string.h> int main(int argc, char** argv) { char buffer[500]; strcpy(buffer, argv[1]); return 0; } ```