【问题标题】:Why and how gcc emits warning for gets()?gcc 为什么以及如何为gets() 发出警告?
【发布时间】:2015-09-28 17:35:24
【问题描述】:
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;
}

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

警告:gets 函数很危险,不应使用!

【问题讨论】:

  • 编译器警告和编译器错误 - 都是不同的。可能是相关的,是的,但是,非常不同。
  • 是的,gets 已贬值,现在在引入 c11.gets_s 作为更安全的替代方案后将其删除。
  • 使用像fgets(array, sizeof(arr), stdin)scanf("%[^\n]%*c", arr) 这样的fget 记得在fgets 的情况下砍掉\n
  • @ARBY 请注意,gets_s() 只是出于向后兼容的原因,标准本身建议使用 fgets()。

标签: c gcc gets


【解决方案1】:

关于问题:

gets() 函数存在缓冲区溢出的危险,并且根据C11 标准从标准C 中删除。编译器可能会支持它们以向后兼容遗留代码。

FWIW,这个警告不是由gcc 自己发出的。最有可能的是,glibc 包含导致编译器发出警告的编译指示。 Ref

关于错误:

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

【讨论】:

    【解决方案2】:

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

    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
    

    【讨论】:

      【解决方案3】:

      您没有向我们展示您是如何声明变量message 作为参数传递给gets 的。假设是

      char message[100];
      

      现在假设您的程序最终尝试读取的实际输入行是 200 个字符长。数组将溢出,可能带来灾难性的后果。 (说真的:使用gets 导致了诚实的重大安全漏洞。)

      无论您的数组有多大,输入可能总是更大,并且无法防止溢出,因为无法告诉gets您的数组实际上有多大。这就是为什么你永远不应该使用它。

      【讨论】:

        猜你喜欢
        • 2021-12-27
        • 1970-01-01
        • 1970-01-01
        • 2018-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-19
        • 1970-01-01
        相关资源
        最近更新 更多