-2
#include <conio.h>
#include <windows.h>
#include <stdio.h>

int main ()
{
char input[255];
int i = 0;
for(;;i++) /* Infinite loop, exited when RETURN is pressed */
{
    char temp;
    temp = getch (); /* Get the current character of the password */
    if (GetAsyncKeyState (VK_RETURN)) /* If the user has pressed return */
    {
        input[i]='\0';
        break;
    }
    input[i] = temp;
    printf("*"); /* Print a star */
}
//printf("%s",input);
if(strcmp(input,"kamal")==0)
{
                     printf("ACCEPTED");
                     }
                     else
                     printf("not");
_getch();
return EXIT_SUCCESS; /* Program was executed successfully */
}

This is my Code. How can i prevent Buffer overflow , if i input password more , then my program crashes. is there anyway i can overcome the problem of this ?

Kamal Kafkaesque
  • 57
  • 1
  • 2
  • 7
  • 2
    You need to stop your infinite loop at a sensible point. – Paul Feb 25 '13 at 12:43
  • 1
    *"if i input password more , then my program crashes"* This is not English... Could you try to clarify the reason of the crashes, as it is quite unclear? Otherwise it would hard to help you any further – Veger Feb 25 '13 at 12:46
  • if i more character than 255 it crashes , and it makes my program vulnerable. – Kamal Kafkaesque Feb 25 '13 at 13:01

5 Answers5

2

Local variable char input[255] stored in the stack. There is no boundary check for array in C. Problem is that when we add more than 255 characters the value of the other variable stored in the stack may get changed. This may cause crash.

one solution is you read the characters and assign only to input array if range (i) less than 255.

#include <conio.h>
#include <windows.h>
#include <stdio.h>

int main ()
{
    char input[255];
    int i = 0;
    int flag = 0;
   for(;;i++) /* Infinite loop, exited when RETURN is pressed */
   {
       char temp;
       temp = getch (); /* Get the current character of the password */
       if (GetAsyncKeyState (VK_RETURN)) /* If the user has pressed return */
       {
           input[i]='\0';
           break;
       }
       if ( i< 255)
       {
            input[i] = temp;
       }
       else     
       {
           flag = 1;
       }

       printf("*"); /* Print a star */
 }
//printf("%s",input);
if(strcmp(input,"kamal")==0 && flag == 0)
{
      printf("ACCEPTED");
 }
 else
       printf("not");
 getch();
 return EXIT_SUCCESS; /* Program was executed successfully */
}

Another solution is to dynamically allocate (realloc()) size of the input array.

Rajesh
  • 182
  • 1
  • 2
  • 9
1

Always check the bounds. Always check the value of i against the length of the buffer.

Mike Sherrill 'Cat Recall'
  • 91,602
  • 17
  • 122
  • 185
1

In some cases, it's acceptable to expand the buffer. This is rarely ideal, since unbounded expansion can cause other problems.

In other cases, it's acceptable to truncate input. This might be an option here, but it's not ideal either.

In this case, as you're comparing against a string that doesn't change, you could skip the "store the input in an array" stage and compare the input as it's recieved, byte by byte, to the password. Such code ought to look something like this, though beware as this is untested:

char password[] = "kamal";
size_t position = 0;
char c = getch();
while (password[position] != '\0' || strchr("\r\n", (unsigned char) c) == NULL) {
    if (c != password[position++] || position == sizeof password) {
        // Password mismatch. Discard the rest of the password, then tell the user...
        while (strchr("\r\n", (unsigned char) c) == NULL) {
            c = getch();
        }
        position = 0;
        puts("Invalid password. Please retry.");
    }
    c = getch();
}

... If there is no buffer to overflow, then what are you worried about?

autistic
  • 1
  • 3
  • 35
  • 80
0

Try wrapping something like:

if(i<255) {
    ...
}

...around your character collection process.

-- EDIT --

#include <conio.h>
#include <windows.h>
#include <stdio.h>

int main ()
{
char input[255];
int i = 0;
for(;;i++) /* Infinite loop, exited when RETURN is pressed */
{
    if(i < 255) 
    {
        char temp;
        temp = getch (); /* Get the current character of the password */
        if (GetAsyncKeyState (VK_RETURN)) /* If the user has pressed return */
        {
            input[i]='\0';
            break;
        }
        input[i] = temp;
        printf("*"); /* Print a star */
    }
}
//printf("%s",input);
if(strcmp(input,"kamal")==0)
{
                     printf("ACCEPTED");
                     }
                     else
                     printf("not");
_getch();
return EXIT_SUCCESS; /* Program was executed successfully */
}
Paul
  • 4,160
  • 3
  • 30
  • 56
  • Did you test that code? What happens if you try to enter more than 255 chars? zzzap. Undefined behaviour. – autistic Feb 27 '13 at 15:05
  • I was simply using what was already there as an example of wrapping the central character collection section in an `if` block; so, no - I didn't test the code. I knew that the code wouldn't work as it won't ever be able to exit. – Paul Feb 27 '13 at 19:36
0

As you indicate, you program crashes if the user provides more than 255 characters.

So, you should check the amount of characters that are already provided, if it reaches the maximum (of your buffer), you should stop grabbing more keys (as the password is already wrong, it does not really matter...):

#define BUFFER_MAX 255

// +1 so we can always add the 0-terminator
char input[BUFFER_MAX + 1];
do {
    char temp;
    temp = getch (); /* Get the current character of the password */
    // Check if char does fit in the buffer
    if(i < BUFFER_MAX) {
        // add to buffer
        input[i] = temp;
        i++;
    }
    printf("*"); /* Print a star */
    // Check if the user pressed return
} while(GetAsyncKeyState (VK_RETURN) == false);
input[i]='\0';

Note: I also rearranged your loop, as it is 'ugly' (bad practice and unnecessary in this case) to use infinite loops and breaking from them...

Veger
  • 37,240
  • 11
  • 105
  • 116
  • Hey Veger , Can u provide me the final total code , it would be highly appreciable. – Kamal Kafkaesque Feb 25 '13 at 13:15
  • Well... just put it in your main function and keep the password check part! (Oh... and place the macro (`#define`) outside the main function...) – Veger Feb 25 '13 at 13:23
  • compiler is having an error at the line while(GetAsyncKeyState (VK_RETURN) == false); saying false is undefined , define it first – Kamal Kafkaesque Feb 27 '13 at 12:31
  • `false` is defined as `0`. So either define it (or find a definition) or just replace it with `0`. – Veger Feb 27 '13 at 12:46