1

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]);

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

this is the only answer that correctly takes stack growth direction into account as well
@NPE : Thanks. I checked the address of fg and filename. fg is placed below the filename. But I have a doubt. when the stack gets loaded, the parameters,return address,local variables gets stored onto the stack in the order. So the local variables fg has to get the highest address than filename. And the array filename grows from lower to higher sddress. Why filename has the highest address than fg.
@Angus: Maybe whoever wrote the example was talking about a system with downward stack, but the system you tested on uses an upward stack.
I tried to declare the fg below the declaration of filename. then also fg occupies the lowest address. if I declare above filename also I get fg as lowest address. when the local varibles gets pused onto stack, the first declared variable has to get the highest address than the one below is my understanding
2

fg is on the stack. So is filename. When you strcpy() something to filename that is larger than 16 it will overwrite fg.

Comments

1

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.

4 Comments

strncpy() is a bad advice. A very bad advice.
@joop yes I agree. I wouldn't even use that method myself. I only showed it in practice since others offered it and wanted to make it more "visible". I've removed it.
why is strncpy() bad advice?
@TritonMan strncpy has it's place in some scenarios, but in this context, using strncpy would just truncate the user's file name if it's too long. So you'd fail somewhere else (e.g., cannot open file).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.