what is stack smashing (C)?

我的未来我决定 提交于 2020-05-25 05:13:11

问题


Code:

int str_join(char *a,  const char *b) {
   int sz =0; 
   while(*a++) sz++;  
   char *st = a -1, c;  
   *st = (char) 32;
   while((c = *b++)) *++st = c;  
   *++st = 0;
   return sz;
}

....

char a[] = "StringA"; 
printf("string-1 length = %d, String a = %s\n", str_join(&a[0],"StringB"), a);

Output:

string-1 length = 7, char *a = StringA StringB

*** stack smashing detected **** : /T02 terminated

Aborted (core dumped)

I don't understand why it's showing stack smashing? and what is *stack smashing? Or is it my compiler's error?


回答1:


Well, stack smashing or stack buffer overflow is a rather detailed topic to be discussed here, you can refer to this wiki article for more info.

Coming to the code shown here, the problem is, your array a is not large enough to hold the final concatenated result.

Thereby, by saying

 while((c = *b++)) *++st = c;

you're essentially accessing out of bound memory which invokes undefined behavior. This is the reason you're getting the "stack smashing" issue because you're trying to access memory which does not belong to your process.

To solve this, you need to make sure that array a contains enough space to hold both the first and second string concatenated together. You have to provide a larger destination array, in short.




回答2:


Stack smashing means you've written outside of ("smashed" past/through) the function's storage space for local variables (this area is called the "stack", in most systems and programming languages). You may also find this type of error called "stack overflow" and/or "stack underflow".

In your code, C is probably putting the string pointed to by a on the stack. In your case, the place that causes the stack-smash is when you increment st beyond the original a pointer and write to where it points, you're writing outside the area the C compiler guarantees to have reserved for the original string assigned into a.

Whenever you write outside an area of memory that is already properly "reserved" in C, that's "undefined behavior" (which just means that the C language/standard doesn't say what happens): usually, you end up overwriting something else in your program's memory (programs typically put other information right next to your variables on the stack, like return addresses and other internal details), or your program tries writing outside of the memory the operating system has "allowed" it to use. Either way, the program typically breaks, sometimes immediately and obviously (for example, with a "segmentation fault" error), sometimes in very hidden ways that don't become obvious until way later.

In this case, your compiler is building your program with special protections to detect this problem and so your programs exits with an error message. If the compiler didn't do that, your program would try to continue to run, except it might end up doing the wrong thing and/or crashing.

The solution comes down to needing to explicitly tell your code to have enough memory for your combined string. You can either do this by explicitly specifying the length of the "a" array to be long enough for both strings, but that's usually only sufficient for simple uses where you know in advance how much space you need. For a general-purpose solution, you'd use a function like malloc to get a pointer to a new chunk of memory from the operating system that has the size you need/want once you've calculated what the full size is going to be (just remember to call free on pointers that you get from malloc and similar functions once you're done with them).



来源:https://stackoverflow.com/questions/40416516/what-is-stack-smashing-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!