Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect offending code for stack smashing error

In a complex program, I am encountering a stack smashing error, pasted below. I'm having trouble to find out where it happens. I located the function using printf-debugging, and noticed that the check actually happens during function return (the printf just before the return is executed, the one just after the function call is not).

However, it's a huge function; I've read it all, but didn't notice any stack overflow opportunities in it. I therefore need a better estimate of where the bug is. How can I debug this further?

I think it would be easiest if I could add a debugger watchpoint on the stack smashing detection memory, so it interrupts execution at the time of smashing instead of at function return. If so, how can I know which memory this is?

For those who want to see source, I recommend looking at any of the stack smashing questions here on Stack Overflow. If you really want to see the code I'm using, get the freedink source (the offending function is updateFrame).

Update

On the gcc-patches list, this issue was discussed in 2009. It doesn't seem to have reached a conclusion though. At least I don't see any name come up when I say "info locals" in gdb (as is suggested somewhere in that thread). If someone can tell me how to find this __stack_guard__ (which isn't working, as it was sort-of rejected), that would answer my question.

Next update

Ok, after lots of searching, I found something completely unexpected. As you can see from the stack backtrace, the stack smashing is detected when exiting a libSDL function. Now normally SDL functions work fine, and freedink is full of bugs. So I didn't even think I could have hit a bug in SDL. However, it seems I did. It is trying to play a midi file. If I copy a different midi file to its place, the program works fine.

So my current problem is solved, but my question is still not answered. Although the stack backtrace does point to the function where the stack is smashed (so it is more useful than I thought), it doesn't provide an address for the guard, which may be useful as well (for setting a watchpoint).

*** stack smashing detected ***: freedink terminated
======= Backtrace: =========
/lib/i386-linux-gnu/i686/cmov/libc.so.6(__fortify_fail+0x50)[0xb754c3f0]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(+0xea39a)[0xb754c39a]
/usr/lib/i386-linux-gnu/libSDL_mixer-1.2.so.0(+0x1c524)[0xb771f524]
/usr/lib/i386-linux-gnu/libSDL_mixer-1.2.so.0(+0x17443)[0xb771a443]
======= Memory map: ========
08048000-0808b000 r-xp 00000000 08:02 4333161    /usr/games/freedink
0808b000-0808c000 rw-p 00042000 08:02 4333161    /usr/games/freedink
0808c000-0841d000 rw-p 00000000 00:00 0
09fa9000-0b2de000 rw-p 00000000 00:00 0          [heap]
afda8000-b09e5000 rw-p 00000000 00:00 0
b0a00000-b0a21000 rw-p 00000000 00:00 0
b0a21000-b0b00000 ---p 00000000 00:00 0
b0ba7000-b0bc3000 r-xp 00000000 08:02 6422698    /lib/i386-linux-gnu/libgcc_s.so.1
b0bc3000-b0bc4000 rw-p 0001b000 08:02 6422698    /lib/i386-linux-gnu/libgcc_s.so.1
b0bea000-b0bec000 rw-p 00000000 00:00 0
b0bec000-b0bed000 r--p 00000000 08:02 4361451    /usr/share/locale/nl/LC_MESSAGES/freedink.mo
b0bed000-b0e69000 rw-p 00000000 00:00 0
b0ea2000-b127f000 rw-p 00000000 00:00 0
b12d7000-b12f0000 rw-p 00000000 00:00 0
b130e000-b1330000 r--p 00000000 08:02 4348594    /usr/share/locale/nl/LC_MESSAGES/libc.mo
b13a1000-b13dd000 rw-p 00000000 00:00 0
b13fa000-b13fb000 ---p 00000000 00:00 0
b13fb000-b1bfb000 rw-p 00000000 00:00 0
b1bfb000-b1c05000 r--p 00000000 08:02 4355730    /usr/share/locale/nl/LC_MESSAGES/pulseaudio.mo
b1c05000-b5c06000 rw-s 00000000 00:11 1297260    /run/shm/pulse-shm-3619928632
b5c06000-b5c9f000 rw-p 00000000 00:00 0
b5c9f000-b5dcb000 rw-s 00000000 00:04 1900555    /SYSV00000000 (deleted)
b5dcb000-b5e22000 rw-p 00000000 00:00 0
b5e35000-b5ecd000 rw-p 00000000 00:00 0
b5ecd000-b5ed2000 r-xp 00000000 08:02 4332397    /usr/lib/i386-linux-gnu/libXfixes.so.3.1.0
b5ed2000-b5ed3000 rw-p 00004000 08:02 4332397    /usr/lib/i386-linux-gnu/libXfixes.so.3.1.0
b5ed3000-b5edb000 r-xp 00000000 08:02 4342806    /usr/lib/i386-linux-gnu/libXrender.so.1.3.0
b5edb000-b5edc000 rw-p 00008000 08:02 4342806    /usr/lib/i386-linux-gnu/libXrender.so.1.3.0
b5edc000-b5ee5000 r-xp 00000000 08:02 4336027    /usr/lib/i386-linux-gnu/libXcursor.so.1.0.2
b5ee5000-b5ee6000 rw-p 00009000 08:02 4336027    /usr/lib/i386-linux-gnu/libXcursor.so.1.0.2
b5ee6000-b5ee7000 ---p 00000000 00:00 0
b5ee7000-b66e7000 rw-p 00000000 00:00 0
b66e7000-b685e000 r--p 00000000 08:02 4338396    /usr/lib/locale/locale-archive
b685e000-b6862000 rw-p 00000000 00:00 0
b6862000-b6872000 r-xp 00000000 08:02 6554164    /lib/i386-linux-gnu/i686/cmov/libresolv-2.13.so
b6872000-b6873000 r--p 00010000 08:02 6554164    /lib/i386-linux-gnu/i686/cmov/libresolv-2.13.so
b6873000-b6874000 rw-p 00011000 08:02 6554164    /lib/i386-linux-gnu/i686/cmov/libresolv-2.13.so
b6874000-b6876000 rw-p 00000000 00:00 0
b6876000-b69dc000 r-xp 00000000 08:02 4327161    /usr/lib/i386-linux-gnu/libvorbisenc.so.2.0.8
b69dc000-b69ed000 r--p 00165000 08:02 4327161    /usr/lib/i386-linux-gnu/libvorbisenc.so.2.0.8
b69ed000-b69ee000 rw-p 00176000 08:02 4327161    /usr/lib/i386-linux-gnu/libvorbisenc.so.2.0.8
b69ee000-b69ef000 rw-p 00000000 00:00 0
b69ef000-b6a02000 r-xp 00000000 08:02 6554172    /lib/i386-linux-gnu/i686/cmov/libnsl-2.13.so
b6a02000-b6a03000 r--p 00012000 08:02 6554172    /lib/i386-linux-gnu/i686/cmov/libnsl-2.13.so
b6a03000-b6a04000 rw-p 00013000 08:02 6554172    /lib/i386-linux-gnu/i686/cmov/libnsl-2.13.so
b6a04000-b6a06000 rw-p 00000000 00:00 0
b6a06000-b6a14000 r-xp 00000000 08:02 4334619    /usr/lib/i386-linux-gnu/libXi.so.6.1.0
b6a14000-b6a15000 rw-p 0000d000 08:02 4334619    /usr/lib/i386-linux-gnu/libXi.so.6.1.0
b6a15000-b6a19000 r-xp 00000000 08:02 6422575    /lib/i386-linux-gnu/libuuid.so.1.3.0
b6a19000-b6a1a000 r--p 00003000 08:02 6422575    /lib/i386-linux-gnu/libuuid.so.1.3.0
b6a1a000-b6a1b000 rw-p 00004000 08:02 6422575    /lib/i386-linux-gnu/libuuid.so.1.3.0
b6a1b000-b6a20000 r-xp 00000000 08:02 4331837    /usr/lib/i386-linux-gnu/libXdmcp.so.6.0.0
b6a20000-b6a21000 rw-p 00004000 08:02 4331837    /usr/lib/i386-linux-gnu/libXdmcp.so.6.0.0
b6a21000-b6a23000 r-xp 00000000 08:02 4330387    /usr/lib/i386-linux-gnu/libXau.so.6.0.0
b6a23000-b6a24000 rw-p 00001000 08:02 4330387    /usr/lib/i386-linux-gnu/libXau.so.6.0.0
b6a24000-b6a25000 rw-p 00000000 00:00 0
b6a25000-b6a29000 r-xp 00000000 08:02 6423604    /lib/i386-linux-gnu/libattr.so.1.1.0
b6a29000-b6a2a000 r--p 00003000 08:02 6423604    /lib/i386-linux-gnu/libattr.so.1.1.0
b6a2a000-b6a2b000 rw-p 00004000 08:02 6423604    /lib/i386-linux-gnu/libattr.so.1.1.0
b6a2b000-b6a30000 r-xp 00000000 08:02 4331630    /usr/lib/i386-linux-gnu/libasyncns.so.0.3.1
b6a30000-b6a31000 rw-p 00004000 08:02 4331630    /usr/lib/i386-linux-gnu/libasyncns.so.0.3.1
b6a31000-b6a9e000 r-xp 00000000 08:02 4375323    /usr/lib/i386-linux-gnu/libsndfile.so.1.0.25
b6a9e000-b6aa0000 r--p 0006c000 08:02 4375323    /usr/lib/i386-linux-gnu/libsndfile.so.1.0.25
b6aa0000-b6aa1000 rw-p 0006e000 08:02 4375323    /usr/lib/i386-linux-gnu/libsndfile.so.1.0.25
b6aa1000-b6aa5000 rw-p 00000000 00:00 0
b6aa5000-b6aad000 r-xp 00000000 08:02 6422615    /lib/i386-linux-gnu/libwrap.so.0.7.6
b6aad000-b6aae000 r--p 00007000 08:02 6422615    /lib/i386-linux-gnu/libwrap.so.0.7.6
b6aae000-b6aaf000 rw-p 00008000 08:02 6422615    /lib/i386-linux-gnu/libwrap.so.0.7.6
b6aaf000-b6ab4000 r-xp 00000000 08:02 4331851    /usr/lib/i386-linux-gnu/libXtst.so.6.1.0
b6ab4000-b6ab5000 rw-p 00004000 08:02 4331851    /usr/lib/i386-linux-gnu/libXtst.so.6.1.0
b6ab5000-b6ab6000 rw-p 00000000 00:00 0
b6ab6000-b6abd000 r-xp 00000000 08:02 4332239    /usr/lib/i386-linux-gnu/libSM.so.6.0.1
b6abd000-b6abe000 rw-p 00006000 08:02 4332239    /usr/lib/i386-linux-gnu/libSM.so.6.0.1
b6abe000-b6ad4000 r-xp 00000000 08:02 4332225    /usr/lib/i386-linux-gnu/libICE.so.6.3.0
b6ad4000-b6ad6000 rw-p 00015000 08:02 4332225    /usr/lib/i386-linux-gnu/libICE.so.6.3.0
b6ad6000-b6ad7000 rw-p 00000000 00:00 0
b6ad7000-b6ad8000 r-xp 00000000 08:02 4326690    /usr/lib/i386-linux-gnu/libX11-xcb.so.1.0.0
b6ad8000-b6ad9000 rw-p 00000000 08:02 4326690    /usr/lib/i386-linux-gnu/libX11-xcb.so.1.0.0
b6ad9000-b6af6000 r-xp 00000000 08:02 6423599    /lib/i386-linux-gnu/libtinfo.so.5.9
b6af6000-b6af8000 r--p 0001c000 08:02 6423599    /lib/i386-linux-gnu/libtinfo.so.5.9
b6af8000-b6af9000 rw-p 0001e000 08:02 6423599    /lib/i386-linux-gnu/libtinfo.so.5.9
b6af9000-b6b2a000 r-xp 00000000 08:02 6423581    /lib/i386-linux-gnu/libncursesw.so.5.9
b6b2a000-b6b2b000 r--p 00030000 08:02 6423581    /lib/i386-linux-gnu/libncursesw.so.5.9
b6b2b000-b6b2c000 rw-p 00031000 08:02 6423581    /lib/i386-linux-gnu/libncursesw.so.5.9
b6b2c000-b6b2d000 rw-p 00000000 00:00 0
b6b2d000-b6c15000 r-xp 00000000 08:02 6423605    /lib/i386-linux-gnu/libslang.so.2.2.4
b6c15000-b6c17000 r--p 000e8000 08:02 6423605    /lib/i386-linux-gnu/libslang.so.2.2.4
b6c17000-b6c26000 rw-p 000ea000 08:02 6423605    /lib/i386-linux-gnu/libslang.so.2.2.4
b6c26000-b6c60000 rw-p 00000000 00:00 0
b6c60000-b6c81000 r-xp 00000000 08:02 4331073    /usr/lib/i386-linux-gnu/libxcb.so.1.1.0
b6c81000-b6c82000 r--p 00020000 08:02 4331073    /usr/lib/i386-linux-gnu/libxcb.so.1.1.0
b6c82000-b6c83000 rw-p 00021000 08:02 4331073    /usr/lib/i386-linux-gnu/libxcb.so.1.1.0
b6c83000-b6ccc000 r-xp 00000000 08:02 6422562    /lib/i386-linux-gnu/libdbus-1.so.3.7.2
b6ccc000-b6ccd000 ---p 00049000 08:02 6422562    /lib/i386-linux-gnu/libdbus-1.so.3.7.2
b6ccd000-b6cce000 r--p 00049000 08:02 6422562    /lib/i386-linux-gnu/libdbus-1.so.3.7.2
b6cce000-b6ccf000 rw-p 0004a000 08:02 6422562    /lib/i386-linux-gnu/libdbus-1.so.3.7.2
b6ccf000-b6cd7000 r-xp 00000000 08:02 4327592    /usr/lib/i386-linux-gnu/libjson.so.0.1.0
b6cd7000-b6cd8000 r--p 00007000 08:02 4327592    /usr/lib/i386-linux-gnu/libjson.so.0.1.0
b6cd8000-b6cd9000 rw-p 00008000 08:02 4327592    /usr/lib/i386-linux-gnu/libjson.so.0.1.0
b6cd9000-b6cdd000 r-xp 00000000 08:02 6423193    /lib/i386-linux-gnu/libcap.so.2.22
b6cdd000-b6cde000 rw-p 00003000 08:02 6423193    /lib/i386-linux-gnu/libcap.so.2.22
b6cde000-b6cdf000 rw-p 00000000 00:00 0
b6cdf000-b6d45000 r-xp 00000000 08:02 4339765    /usr/lib/i386-linux-gnu/pulseaudio/libpulsecommon-2.0.so
b6d45000-b6d46000 r--p 00065000 08:02 4339765    /usr/lib/i386-linux-gnu/pulseaudio/libpulsecommon-2.0.so
b6d46000-b6d47000 rw-p 00066000 08:02 4339765    /usr/lib/i386-linux-gnu/pulseaudio/libpulsecommon-2.0.so
b6d47000-b6d4e000 r-xp 00000000 08:02 6554189    /lib/i386-linux-gnu/i686/cmov/librt-2.13.so
b6d4e000-b6d4f000 r--p 00006000 08:02 6554189    /lib/i386-linux-gnu/i686/cmov/librt-2.13.so
b6d4f000-b6d50000 rw-p 00007000 08:02 6554189    /lib/i386-linux-gnu/i686/cmov/librt-2.13.so
b6d50000-b6d5b000 r-xp 00000000 08:02 4330586    /usr/lib/i386-linux-gnu/libjbig.so.0.0.0
b6d5b000-b6d5e000 rw-p 0000b000 08:02 4330586    /usr/lib/i386-linux-gnu/libjbig.so.0.0.0
b6d5e000-b6d64000 r-xp 00000000 08:02 4333085    /usr/lib/i386-linux-gnu/libogg.so.0.8.0
b6d64000-b6d65000 rw-p 00005000 08:02 4333085    /usr/lib/i386-linux-gnu/libogg.so.0.8.0
b6d65000-b6d66000 rw-p 00000000 00:00 0
b6d66000-b6d8c000 r-xp 00000000 08:02 6426268    /lib/i386-linux-gnu/libexpat.so.1.6.0
b6d8c000-b6d8d000 ---p 00026000 08:02 6426268    /lib/i386-linux-gnu/libexpat.so.1.6.0
b6d8d000-b6d8f000 r--p 00026000 08:02 6426268    /lib/i386-linux-gnu/libexpat.so.1.6.0
b6d8f000-b6d90000 rw-p 00028000 08:02 6426268    /lib/i386-linux-gnu/libexpat.so.1.6.0
b6d90000-b6da5000 r-xp 00000000 08:02 6553829    /lib/i386-linux-gnu/i686/cmov/libpthread-2.13.so
b6da5000-b6da6000 r--p 00014000 08:02 6553829    /lib/i386-linux-gnu/i686/cmov/libpthread-2.13.so
b6da6000-b6da7000 rw-p 00015000 08:02 6553829    /lib/i386-linux-gnu/i686/cmov/libpthread-2.13.so
b6da7000-b6da9000 rw-p 00000000 00:00 0
b6da9000-b6dab000 r-xp 00000000 08:02 4338554    /usr/lib/i386-linux-gnu/libts-0.0.so.0.1.1
b6dab000-b6dac000 rw-p 00001000 08:02 4338554    /usr/lib/i386-linux-gnu/libts-0.0.so.0.1.1
b6dac000-b6e73000 r-xp 00000000 08:02 4326574    /usr/lib/i386-linux-gnu/libcaca.so.0.99.18
b6e73000-b6e74000 rw-p 000c6000 08:02 4326574    /usr/lib/i386-linux-gnu/libcaca.so.0.99.18
b6e74000-b6e79000 rw-p 00000000 00:00 0
b6e79000-b6e8f000 r-xp 00000000 08:02 4353038    /usr/lib/i386-linux-gnu/libdirect-1.2.so.9.0.1
b6e8f000-b6e90000 rw-p 00016000 08:02 4353038    /usr/lib/i386-linux-gnu/libdirect-1.2.so.9.0.1
b6e90000-b6e91000 rw-p 00000000 00:00 0
b6e91000-b6e9a000 r-xp 00000000 08:02 4353034    /usr/lib/i386-linux-gnu/libfusion-1.2.so.9.0.1
b6e9a000-b6e9b000 rw-p 00008000 08:02 4353034    /usr/lib/i386-linux-gnu/libfusion-1.2.so.9.0.1
b6e9b000-b6f1e000 r-xp 00000000 08:02 4353040    /usr/lib/i386-linux-gnu/libdirectfb-1.2.so.9.0.1
b6f1e000-b6f21000 rw-p 00082000 08:02 4353040    /usr/lib/i386-linux-gnu/libdirectfb-1.2.so.9.0.1
b6f21000-b6f32000 r-xp 00000000 08:02 4325458    /usr/lib/i386-linux-gnu/libXext.so.6.4.0
b6f32000-b6f33000 rw-p 00010000 08:02 4325458    /usr/lib/i386-linux-gnu/libXext.so.6.4.0
b6f33000-b7067000 r-xp 00000000 08:02 4327567    /usr/lib/i386-linux-gnu/libX11.so.6.3.0
b7067000-b706b000 rw-p 00133000 08:02 4327567    /usr/lib/i386-linux-gnu/libX11.so.6.3.0
b706b000-b70b9000 r-xp 00000000 08:02 4339764    /usr/lib/i386-linux-gnu/libpulse.so.0.14.2
b70b9000-b70ba000 r--p 0004d000 08:02 4339764    /usr/lib/i386-linux-gnu/libpulse.so.0.14.2
b70ba000-b70bb000 rw-p 0004e000 08:02 4339764    /usr/lib/i386-linux-gnu/libpulse.so.0.14.2
b70bb000-b70bc000 rw-p 00000000 00:00 0
b70bc000-b70bf000 r-xp 00000000 08:02 4330214    /usr/lib/i386-linux-gnu/libpulse-simple.so.0.0.3
b70bf000-b70c0000 r--p 00002000 08:02 4330214    /usr/lib/i386-linux-gnu/libpulse-simple.so.0.0.3
b70c0000-b70c1000 rw-p 00003000 08:02 4330214    /usr/lib/i386-linux-gnu/libpulse-simple.so.0.0.3
b70c1000-b71b4000 r-xp 00000000 08:02 4328460    /usr/lib/i386-linux-gnu/libasound.so.2.0.0
b71b4000-b71b8000 r--p 000f2000 08:02 4328460    /usr/lib/i386-linux-gnu/libasound.so.2.0.0
b71b8000-b71b9000 rw-p 000f6000 08:02 4328460    /usr/lib/i386-linux-gnu/libasound.so.2.0.0
b71b9000-b7250000 r-xp 00000000 08:02 4330930    /usr/lib/i386-linux-gnu/libfreetype.so.6.8.1
b7250000-b7254000 r--p 00096000 08:02 4330930    /usr/lib/i386-linux-gnu/libfreetype.so.6.8.1
b7254000-b7255000 rw-p 0009a000 08:02 4330930    /usr/lib/i386-linux-gnu/libfreetype.so.6.8.1
b7255000-b7283000 r-xp 00000000 08:02 4327431    /usr/lib/i386-linux-gnu/libwebp.so.2.0.0
b7283000-b7284000 r--p 0002d000 08:02 4327431    /usr/lib/i386-linux-gnu/libwebp.so.2.0.0
b7284000-b7285000 rw-p 0002e000 08:02 4327431    /usr/lib/i386-linux-gnu/libwebp.so.2.0.0
b7285000-b7288000 rw-p 00000000 00:00 0
b7288000-b729f000 r-xp 00000000 08:02 6422674    /lib/i386-linux-gnu/libz.so.1.2.7
b729f000-b72a0000 r--p 00016000 08:02 6422674    /lib/i386-linux-gnu/libz.so.1.2.7
b72a0000-b72a1000 rw-p 00017000 08:02 6422674    /lib/i386-linux-gnu/libz.so.1.2.7
b72a1000-b72a2000 rw-p 00000000 00:00 0
b72a2000-b7304000 r-xp 00000000 08:02 4328894    /usr/lib/i386-linux-gnu/libtiff.so.4.3.6
b7304000-b7305000 ---p 00062000 08:02 4328894    /usr/lib/i386-linux-gnu/libtiff.so.4.3.6
b7305000-b7307000 r--p 00062000 08:02 4328894    /usr/lib/i386-linux-gnu/libtiff.so.4.3.6
b7307000-b7308000 rw-p 00064000 08:02 4328894    /usr/lib/i386-linux-gnu/libtiff.so.4.3.6
b7308000-b7340000 r-xp 00000000 08:02 4325500    /usr/lib/i386-linux-gnu/libjpeg.so.8.4.0
b7340000-b7341000 rw-p 00037000 08:02 4325500    /usr/lib/i386-linux-gnu/libjpeg.so.8.4.0
b7341000-b7369000 r-xp 00000000 08:02 6422719    /lib/i386-linux-gnu/libpng12.so.0.49.0
b7369000-b736a000 r--p 00027000 08:02 6422719    /lib/i386-linux-gnu/libpng12.so.0.49.0
b736a000-b736b000 rw-p 00028000 08:02 6422719    /lib/i386-linux-gnu/libpng12.so.0.49.0
b736b000-b7381000 r-xp 00000000 08:02 4334103    /usr/lib/libmad.so.0.2.1
b7381000-b7382000 rw-p 00015000 08:02 4334103    /usr/lib/libmad.so.0.2.1
b7382000-b73d0000 r-xp 00000000 08:02 4331056    /usr/lib/i386-linux-gnu/libFLAC.so.8.2.0
b73d0000-b73d1000 r--p 0004d000 08:02 4331056    /usr/lib/i386-linux-gnu/libFLAC.so.8.2.0
b73d1000-b73d2000 rw-p 0004e000 08:02 4331056    /usr/lib/i386-linux-gnu/libFLAC.so.8.2.0
b73d2000-b73d3000 rw-p 00000000 00:00 0
b73d3000-b73fd000 r-xp 00000000 08:02 4328031    /usr/lib/i386-linux-gnu/libvorbis.so.0.4.5
b73fd000-b73fe000 r--p 00029000 08:02 4328031    /usr/lib/i386-linux-gnu/libvorbis.so.0.4.5
b73fe000-b73ff000 rw-p 0002a000 08:02 4328031    /usr/lib/i386-linux-gnu/libvorbis.so.0.4.5
b73ff000-b7407000 r-xp 00000000 08:02 4328022    /usr/lib/i386-linux-gnu/libvorbisfile.so.3.3.4
like image 437
Bas Wijnen Avatar asked Nov 30 '12 08:11

Bas Wijnen


People also ask

How is stack smashing detected?

Usually, the compiler generates the stack smashing detected error in response to its defense mechanism against buffer overflows. A buffer​ overflow occurs when the user input exceeds the buffer capacity. The following C code can cause the buffer to overflow if the user enters more than ten characters.


2 Answers

You may want to try this easy step. Pad the stack at both ends with buffers and then examine the contents of the overwritten buffers. Often, examing the contents of the buffers gives a pretty good clue as to where the problem may be.

#include <stdio.h>
#include <string.h>

#define DEBUG           1

/*
 * If stack is getting corrupted then this buf should change. 
 * Looking at the contents of the buf should give a hint at 
 * what is causing it.
 */

#if DEBUG

#define PAD_SIZE        1024
#define PAD_CHAR        0xE5

static void
check_buf(char *name, char *s)
{
    int j, count = 0;

    for (j = 0; j < PAD_SIZE; j++) {
        if ((unsigned char)*s != PAD_CHAR) {
            count++;
        }
        s++;
    }

    if (count != 0) {
        printf("%s corrupted by %d bytes\n", name, count);
    }
}

#endif

/*
 * Stack smashing happens when attempting to return from foo.
 */

int
foo(/* some calling args go here */)
{
#if DEBUG
    char pad_a[PAD_SIZE];
#endif
    /*
     * Rest of your ALL auto variables go here.
     */
#if DEBUG
    char pad_b[PAD_SIZE];

    memset(pad_a, PAD_CHAR, PAD_SIZE);
    memset(pad_b, PAD_CHAR, PAD_SIZE);
#endif
    /*
     * foo does its work and somehow ends up corrupting the
     * stack.  We normally learn about the problem when the
     * function attempts to return.
     */
#if DEBUG
    check_buf("foo():pad_a", pad_a);
    check_buf("foo():pad_b", pad_b);
#endif
    return(1);
}

Let us know how it goes.

like image 168
Arun Taylor Avatar answered Sep 20 '22 05:09

Arun Taylor


Have you used the exp-sgcheck tool for Valgrind or just the memcheck tool? It sounds like sgcheck may do what you want. From the Valgrind docs:

SGCheck and Memcheck are complementary: their capabilities do not overlap. Memcheck performs bounds checks and use-after-free checks for heap arrays. It also finds uses of uninitialised values created by heap or stack allocations. But it does not perform bounds checking for stack or global arrays.

SGCheck, on the other hand, does do bounds checking for stack or global arrays, but it doesn't do anything else.

There are some caveats about how exactly exp-sgcheck find potential errors (and it is considered experimental) so read the docs carefully before trying it out.

Edit:

Here's another idea to try. If you break on function entry can you determine an address that will be corrupted by the time the function exits? Perhaps by getting the address of a stack variable or something? If so you could set a gdb watch point on that address. gdb will stop the program whenever this memory location gets modified. This can be pretty annoying if it's an address that's modified often but can, in a pinch, function as a poor man's stack guard. Here's a link to the docs.

You don't have to have a special stack guard, you just need to watch something on the stack which you know will be corrupted. For example, given the following program:


void bar(int j) {
    int *addr = (&j) - 20;
    for(int i = 0; i &lt= 1000; i++) {
        *(addr + i) = 0xDEADBEEF;
    }
}

int main() {
    bar(10);
    return 0;
}

If you break on entry to bar and set watch j then continue you should get a break when i == 20 inside the loop. If j is supposed to be changed inside the function this is obviously pretty annoying. If you have just an address you can watch that by dereferencing it watch *(int*)0x40051f.

like image 27
asm Avatar answered Sep 20 '22 05:09

asm