为什么以及gcc如何为gets()发出警告?

时间:2015-07-10 05:00:36

标签: c gcc gets

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;
}

这是我计划的一部分。当我编译并运行它时,我收到一个错误。错误的消息是

  

警告:获取功能很危险,不应该使用!

3 个答案:

答案 0 :(得分:3)

简单的谷歌搜索会提供很多有用的信息,比如这个答案。

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

使用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;
}

输入1

thegeekstuff

<强>输出

 Correct Password
 Root privileges given to the user

输入2

abcdefghijklmnopqr    <-- stack smashing

<强>输出

 Wrong Password
 Root privileges given to the user

答案 1 :(得分:3)

关于这个问题:

gets()函数对于缓冲区溢出的风险是危险的,并且按照C标准从标准C11中删除。编译器可能支持它们以便对遗留代码进行向后兼容。

FWIW,gcc本身并不发出此警告。最有可能的是,glibc包含一个pragma,导致编译器发出警告。 Ref

关于错误:

您的编译语句中已启用-Werror,这基本上要求gcc将任何警告视为错误。

答案 2 :(得分:0)

您没有告诉我们您如何将您传递的变量message声明为gets的参数。假设它是

char message[100];

现在假设程序最终尝试读取的实际输入行长度为200个字符。阵列将溢出,可能带来灾难性后果。 (严重的是:使用gets导致了诚实至善的主要安全漏洞。)

无论你的数组有多大,输入可能总是更大,并且没有办法防止溢出,因为没有办法告诉gets你的数组究竟有多大。这就是你永远不应该使用它的原因。