Reputation: 12621
I was going through the security issues in C. I could not understand the below code of how it corrupts the stack,
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int chk_perm(){
printf("\n Check Perm \n");
return 2;
}
int main(int argc,char* argv[]){
int fg;
char filename[16];
if(argc != 2){
fprintf(stderr,"Usage : %s filename\n",argv[0]);
exit(1);
}
fg = chk_perm();
strcpy(filename,argv[1]);
if(fg == 0xdeadbeef){
//execute as root or deposit million dollars in bank account
}
else{
//execute as a normal user , deduct $10 from an account
}
return 0;
}
The argv[1] passed may change the value of fg. Its said, that corruption will happen, if argv[1] passed is an entire binary that can cause undesired results can be passed as an argument along with return address.
I could not understand , how the strcpy corrupts the stack check_perm such that the value of the fg gets changed.
My assumption about the program,
When program starts executing, It creates a stack for the main function and put its arguments,return address,local variables onto the stack.So int fg will occupy 4 bytes (08567500 loc)of the stack and filename[16] will occupy next 16 bytes(08567504). Even if the filename is overflowing more than 16 bytes it may corrupt if any local variable was present after it.
So how does the fg gets corrupted due to strcpy(filename,argv[1]);
Upvotes: 1
Views: 151
Reputation: 58224
As others have pointed out, you are writing past the filename
buffer. When you do, the next item in line on the stack is the fg
variable, so it will get bytes written to it if the input file name is more than 15 characters long (and then one more byte is included: the zero terminator).
You need to either make filename
big enough to hold whatever a user might give you for argv[1]
, or prevent copying too many bytes. But it's best to allocate the space you need in this case:
char filename[PATH_MAX+1];
If you want to do it dynamically:
char *filename;
if ( !(filename = malloc(strlen(argv[1]) + 1))) ) {
... (failure leg)
}
Limiting the file name length to 16
bytes (actually 15
plus zero terminator) is extremely impractical for the user, especially since they may provide a full path name for the file parameter. Using a function like strncpy
risks truncating the user's file name and either generating a file open error or, worse, opening the wrong file.
Upvotes: 1
Reputation: 500177
If on your architecture the stack grows downwards (as is commonly the case), fg
will occupy memory immediately after filename
. This means that when you write past filename
, you smash fg
.
Upvotes: 3
Reputation: 7044
fg
is on the stack. So is filename
. When you strcpy()
something to filename
that is larger than 16 it will overwrite fg
.
Upvotes: 2