I am executing my a.out file. After execution the program runs for some time then exits with the message:
**** stack smashing detected ***: ./a.out terminated*
*======= Backtrace: =========*
*/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)Aborted*
What could be the possible reasons for this and how do I rectify it?
I got this error while using malloc() to allocate some memory to a struct * after spending some this debugging the code, I finally used free() function to free the allocated memory and subsequently the error message gone :)
One scenario would be in the following example:
In this program you can reverse a String or a part of the string if you for example call
reverse()
with something like this:If you decide to pass the length of the array like this:
Works fine too.
But when you do this:
You get get:
And this happens because in the first code, the length of
arr
is checked inside ofrevSTR()
which is fine, but in the second code where you pass the length:the Length is now longer then the actually length you pass when you say
arr + 2
.Length of
strlen ( arr + 2 )
!=strlen ( arr )
.Stack Smashing here is actually caused due to a protection mechanism used by gcc to detect buffer overflow errors. For example in the following snippet:
The compiler, (in this case gcc) adds protection variables (called canaries) which have known values. An input string of size greater than 10 causes corruption of this variable resulting in SIGABRT to terminate the program.
To get some insight, you can try disabling this protection of gcc using option
-fno-stack-protector
while compiling. In that case you will get a different error, most likely a segmentation fault as you are trying to access an illegal memory location. Note that-fstack-protector
should always be turned on for release builds as it is a security feature.You can get some information about the point of overflow by running the program with a debugger. Valgrind doesn't work well with stack-related errors, but like a debugger, it may help you pin-point the location and reason for the crash.
Stack corruptions ususally caused by buffer overflows. You can defend against them by programming defensively.
Whenever you access an array, put an assert before it to ensure the access is not out of bounds. For example:
This makes you think about array bounds and also makes you think about adding tests to trigger them if possible. If some of these asserts can fail during normal use turn them into a regular
if
.Another source of stack smashing is (incorrect) use of
vfork()
instead offork()
.I just debugged a case of this, where the child process was unable to
execve()
the target executable and returned an error code rather than calling_exit()
.Because
vfork()
had spawned that child, it returned while actually still executing within the parent's process space, not only corrupting the parent's stack, but causing two disparate sets of diagnostics to be printed by "downstream" code.Changing
vfork()
tofork()
fixed both problems, as did changing the child'sreturn
statement to_exit()
instead.But since the child code precedes the
execve()
call with calls to other routines (to set the uid/gid, in this particular case), it technically does not meet the requirements forvfork()
, so changing it to usefork()
is correct here.(Note that the problematic
return
statement was not actually coded as such -- instead, a macro was invoked, and that macro decided whether to_exit()
orreturn
based on a global variable. So it wasn't immediately obvious that the child code was nonconforming forvfork()
usage.)For more information, see:
The difference between fork(), vfork(), exec() and clone()
Please look at the following situation:
When I disabled the stack smashing protector no errors were detected, which should have happened when I used "./a.out wepassssssssssssssssss"
So to answer your question above, the message "** stack smashing detected : xxx" was displayed because your stack smashing protector was active and found that there is stack overflow in your program.
Just find out where that occurs, and fix it.