简体   繁体   中英

c stack smashing detected

I've created a file which prints Hello, world as many times at the user wants to give input.

#include <stdio.h>
#include <string.h>
int main() {
    char message[10];
    int count, i;

    strcpy(message, "Hello, world!");

    printf("Repeat how many times? ");
    scanf("%d", &count);

    for(i=0; i < count; i++)
        printf("%3d - %s\n", i, message);
}

No matter what the number entered it always results in a "stack smash". Here is the program, can anyone come up with a conclusion to why it is doing this? Here is the "traceback" that occurs after the stack smash is detected:

sean@blue:~/programming$ ./a.out
Repeat how many times? 12
  0 - Hello, world!
  1 - Hello, world!
  2 - Hello, world!
  3 - Hello, world!
  4 - Hello, world!
  5 - Hello, world!
  6 - Hello, world!
  7 - Hello, world!
  8 - Hello, world!
  9 - Hello, world!
 10 - Hello, world!
 11 - Hello, world!
*** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0x1f8c75]
/lib/i386-linux-gnu/libc.so.6(+0xe8c27)[0x1f8c27]
./a.out[0x8048524]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x129113]
./a.out[0x80483f1]
======= Memory map: ========
00110000-00288000 r-xp 00000000 08:01 1577912    /lib/i386-linux-gnu/libc-2.13.so
00288000-0028a000 r--p 00178000 08:01 1577912    /lib/i386-linux-gnu/libc-2.13.so
0028a000-0028b000 rw-p 0017a000 08:01 1577912    /lib/i386-linux-gnu/libc-2.13.so
0028b000-0028e000 rw-p 00000000 00:00 0 
0036b000-0036c000 r-xp 00000000 00:00 0          [vdso]
00454000-00470000 r-xp 00000000 08:01 1573818    /lib/i386-linux-gnu/libgcc_s.so.1
00470000-00471000 r--p 0001b000 08:01 1573818    /lib/i386-linux-gnu/libgcc_s.so.1
00471000-00472000 rw-p 0001c000 08:01 1573818    /lib/i386-linux-gnu/libgcc_s.so.1
00e7e000-00e9c000 r-xp 00000000 08:01 1573924    /lib/i386-linux-gnu/ld-2.13.so
00e9c000-00e9d000 r--p 0001d000 08:01 1573924    /lib/i386-linux-gnu/ld-2.13.so
00e9d000-00e9e000 rw-p 0001e000 08:01 1573924    /lib/i386-linux-gnu/ld-2.13.so
08048000-08049000 r-xp 00000000 00:14 3801591    /home/sean/programming/a.out
08049000-0804a000 r--p 00000000 00:14 3801591    /home/sean/programming/a.out
0804a000-0804b000 rw-p 00001000 00:14 3801591    /home/sean/programming/a.out
08a9e000-08abf000 rw-p 00000000 00:00 0          [heap]
b77e8000-b77e9000 rw-p 00000000 00:00 0 
b77fc000-b7800000 rw-p 00000000 00:00 0 
bff87000-bffa8000 rw-p 00000000 00:00 0          [stack]
Aborted

Because "Hello, world!" is more than 10 characters...

message can only hold 10 bytes. You are copying the string "Hello World!" which is 13 bytes (if you count the null character) and you will end up overwriting and corrupting the stack protector cookie.

The cookie is a random byte inserted by the compiler to make sure that you crash if the return address is modified on stack, preventing potential buffer overflow exploits.

If you are compiling with gcc, to experiment, try adding -fno-stack-protector switch to your compilation statement and trying again. The program will probably crash (but not with a error message like that) and will be vulnerable to buffer overflow exploits.

Your message array is 10 characters long (0-9), but if you count "Hello, World!" (without the quotes) it is 13 characters long. As such you are overwriting memory that isn't part of your array.

For reference, strcpy() , strcat() and most other C-string functions don't check the length of the array, they assume that you've given it enough space to work with.

So, you'll need to give your message array more space. But how much more? enough to fit "Hello, world!" PLUS one more for the null-terminator character '\\0' , which determines the end of the string. so you'll need to declare an array of 14 characters.

For a bit more in-depth explanation on working with string and the null-character, i suggest this page . Whilst it is a C++ page it covers stuff that is common for both C and C++ (as C++ is based on C)

Also, as Pearsonartphoto said, you can just declare your array as

char message[] = "Hello, World!";

However, if this is for school or a uni assignment, make sure you've been taught to do it this way, because sometimes you can be deducted marks for 'rushing ahead'. The idea of these sort of questions is to teach the funementals, and HOW and WHY certain things work, they may not be the easiest or most efficient way of doing things (the type of stack-smash you're getting is still causing problems in major systems today because programmers forget to check sizes etc).

您的message数组必须至少比您复制到其中的字符串长一个字符(请记住,您还需要保留隐式'\\0' 0'null终止符)。

As has been said, Hello World! is too long. Much easier would be to do the following

char message[]="Hello World!";

Which will be the right size automatically.

I had this problem when i defined a struct in this way:

struct data {
...variables...
char text[];
};

This won't give ANY WARNING but in my case caused a stack smashing error. I solved substituting that with

char text[100];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM