Reputation: 1109
Please explain me the following example. The problem is simple but the results are abrupt.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int flag = 0;
char passwd[10];
strcpy(passwd, argv[1]);
if(0 == strcmp("LinuxGeek", passwd))
{
flag = 1;
}
if(flag)
{
printf("\n Password cracked \n");
}
else
{
printf("\n Incorrect passwd \n");
}
return 0;
}
The value of flag is changing to garbage value after the line
strcpy(passwd, argv[1]);
However, if I define the variable flag like,
int flag = 0
after the line
strcpy(passwd, argv[1]);
I get the desired result. Please explain it to me in brief.
Upvotes: 1
Views: 173
Reputation: 505
When I printed the address of flag
and passwd
I got 0x7fff3315c91c
and 0x7fff3315c910
respectively.
So I concluded that the value of passwd
is overwriting the value of flag if the size of the argv[1] is greater than 12(as the difference between the addresses of flag
and passwd
12).
passwd
address model (0x7fff3315c910):
| 10 | 11 | 12 | ........... | 1A | 1B |
flag
address model (0x7fff3315c91c):
| 1C | ........
From above we can see that the address of flag
is over written by the value of passwd
Upvotes: 2
Reputation: 363807
The short answer is that the behavior of your program is undefined when the length of argv[1]
is greater than nine, because then you overflow the buffer passwd
.
The long answer is that apparently, your compiler orders the variables on the stack in the order listed, so moving flag
after passwd
puts four extra zero bytes after the buffer and strcmp
recognizes one of these as a NUL terminator on passwd
.
The solution to the problem is to skip the useless copying:
char *passwd = argv[1];
Or remove the passwd
variable altogether and do the following comparison:
strcmp("LinuxGeek", argv[1])
Upvotes: 6
Reputation: 3496
You don't perform any check (length, null byte) on the strings you are manipulating, especially argv
. For example the input password might not fit in your passwd
variable.
Upvotes: 1