Why and how gcc emits warning for gets()?

2019-03-07 07:53发布

问题:

while(1)
    {
        printf("\nEnter message : ");
        gets(message);

        //Send some data
        if( send(sock , message , strlen(message) , 0) < 0)
        {
            puts("Send failed");
            return 1;
        }

        //Receive a reply from the server
        if( recv(sock , server_reply , 2000 , 0) < 0)
        {
            puts("recv failed");
            break;
        }

        puts("Server reply :");
        puts(server_reply);
    }

    close(sock);
    return 0;
}

This is part of my program. When I compile and run it, I get an error. The error's message is

warning: the gets function is dangerous and should not be used!

回答1:

A simple google search would have given a lot of useful information like this answer.

https://stackoverflow.com/a/1694042/2425366

A buffer overflow example using gets

#include <stdio.h>
#include <string.h>

int main(void) {
    char buff[15];
    int pass = 0;
    printf("\n Enter the password : \n");
    gets(buff);
    if (strcmp(buff, "thegeekstuff")) {
        printf("\n Wrong Password \n");
    }
    else {
        printf("\n Correct Password \n");
        pass = 1;
    }
    if (pass) {
        /* Now Give root or admin rights to user*/
        printf("\n Root privileges given to the user \n");
    }
    return 0;
}

Input 1

thegeekstuff

Output

 Correct Password
 Root privileges given to the user

Input 2

abcdefghijklmnopqr    <-- stack smashing

Output

 Wrong Password
 Root privileges given to the user


回答2:

Regarding the issue:

gets() function is dangerous for the risk of buffer overflow and dropped from the standard C, as per C11 standard. Compilers may support them for backward compatibility for legacy codes.

FWIW, this warning is not issued by gcc all by itself. Most likely, glibc contains a pragma which causes the compiler to emit the warning. Ref

Regarding the error:

You have -Werror enabled in your compilation statement, which basically asks gcc to treat any warning as error.



回答3:

You didn't show us how you had declared the variable message which you passed as the argument to gets. Suppose it was

char message[100];

Now suppose that the actual line of input that your program ends up trying to read is 200 characters long. The array will overflow, with potentially disastrous results. (Seriously: honest-to-goodness major security breaches have resulted from using gets.)

No matter how big your array is, the input might always be bigger, and there's no way to prevent the overflow, because there's no way to tell gets how big your array actually is. That's why you should never use it.



标签: c gcc gets