Reputation: 35
I was just wondering, cause I have this C code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int fillBuffer(int argc, char *argv[]) {
char bufferA[4] = "aaa";
char bufferB[4] = "bbb";
if(argc > 1)
strcpy(bufferB, argv[1]);
printf("bufferA: %s\n", bufferA);
printf("bufferB: %s\n", bufferB);
return 0;
}
int main(int argc, char *argv[]) {
fillBuffer(argc, argv);
return 0;
}
and I tried turning off the stack protection by using the: -fno-stack-protector
and when I try to run it by doing: ./program (escape key) 5f, the program outputs to:
bufferA: f
bufferB: fffff
I'm just not sure how bufferA becomes f also. Can anyone explain this to me?
Upvotes: 0
Views: 102
Reputation: 1556
Your strcpy call is unsafe, and will corrupt your stack if argv[1] contains more than 3 characters (plus one for the null termination character). Do not hit escape, just space and the 5f and you get the proper output:
scott> a.out 5f
bufferA: aaa
bufferB: 5f
When you hit escape, the shell can add additional characters to the string parameter, and because your strcpy is unsafe (does not check length) it will go beyond the end of your buffer and corrupt your stack. Your buffer is only 4 characters long, so your program will corrupt the stack if a parameter longer than 3 characters is entered.
To fix it, increase your buffer size from 4 to something more reasonable like 60, and use strncpy to ensure that you do not exceed the buffer if the parameter is too long:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_PARM_LEN 60
int fillBuffer(int argc, char *argv[]) {
char bufferA[MAX_PARM_LEN] = "aaa";
char bufferB[MAX_PARM_LEN] = "bbb";
if(argc > 1)
strncpy(bufferB, argv[1], MAX_PARM_LEN);
printf("bufferA: %s\n", bufferA);
printf("bufferB: %s\n", bufferB);
return 0;
}
int main(int argc, char *argv[]) {
fillBuffer(argc, argv);
return 0;
}
One last point: don't turn off stack protection.
Upvotes: 0
Reputation: 59
The local buffer A and B are stored reverse order on your stack. So, on in memory you have 8 bytes starting buffer B then buffer A.
When you strcpy your 5 "f" to buffer B, the first 4 go into buffer B, and the last one with the end string '\0' to buffer A.
Then when you printf your buffers, buffer A contain 1 "f" and the string terminator. That's where it comes from.
Upvotes: 1