【问题标题】:char pointer overflow字符指针溢出
【发布时间】:2010-08-04 23:04:00
【问题描述】:

我是 C 新手,我想知道指针是否可能被 strcpy() 等易受攻击的 C 函数溢出。我在源码中看到了很多,是不是可以避免缓冲区溢出?

【问题讨论】:

    标签: c


    【解决方案1】:

    是的。这实际上是缓冲区溢出漏洞的典型原因。避免溢出缓冲区的唯一方法是确保您不做任何可能导致溢出的事情。对于strcpy,解决方案是使用strncpy,其中包括要复制字符串的缓冲区的大小。

    【讨论】:

    • strncpy 并没有多大帮助,因为如果目标中没有终止空字符的空间,则不会放在那里(即,如果源长于目标大小)。有些人提供的尺寸比实际目的地尺寸小一。
    • strncpy 的 API 很容易用错,而且我已经多次看到它用错了。我不知道为什么人们如此害怕计算缓冲区大小、分配一些内存和使用原始函数......
    • @Thanatos:在这种情况下,当您收到来自用户的缓冲区时,您会怎么做?你甚至不能安全地调用strlen,它可能不是NUL终止的。
    • @torak:当我从用户那里得到一个缓冲区时,它是 NUL 终止的。 (毕竟......我是程序员,我编写了程序?)如果不是,我知道其他形式的长度,比如 aux size_t。如果你有一个缓冲区并且你不知道长度,那么你已经在某个地方搞砸了。
    • @Thantos:某些软件的作者身份无法让您控制其输入。当然,您可以并且应该实施清理/验证检查,但这与控制用户输入不同。
    【解决方案2】:

    当然,如果您没有为缓冲区分配足够的空间,那么您当然可以:

    char* ptr = (char*)malloc(3);
    strcpy(ptr, "this is very, very bad"); /* ptr only has 3 bytes allocated! */
    

    然而,真正糟糕的是,这段代码可以正常工作而不会给您任何错误,但它可能会覆盖某些内存,这可能会导致您的程序稍后崩溃,看似随机,您可能不知道为什么。那些花费大量时间写C 的人都会告诉你,这就是沮丧的几个小时(有时甚至是)的根源。

    这就是为什么使用C,你必须非常小心这些事情,并且双重、三重、n 度检查你的代码。之后,再次检查。

    【讨论】:

      【解决方案3】:

      其他一些方法是

      #define MAX_LENGTH_NAME 256
      
      foo()
      {
      char a[MAX_LENGTH_NAME+1]; // You can also use malloc here
      
      strncpy(a,"Foxy",MAX_LENGTH_NAME);
      
      snprintf(a,MAX_LENGTH_NAME,"%s","Foxy");
      
      }
      

      所以最好知道分配内存的大小,然后使用调用来避免缓冲区溢出。 对已编写代码的静态分析可能会指出这些错误,您也可以对其进行更改。

      【讨论】:

      • 如果 MAX_LENGTH_NAME 为 4(或者如果源字符串的长度为 256 个字符),strncpy() 调用仍会导致未定义的行为,因为 a 数组的最后一个字节仍将未初始化。
      • 如果您知道长度不会超过某个数字,则必须这样做。否则根据需要分配,即源的长度。当然我们也可以使用 asprintf 函数来处理空终止的额外字节。
      • snprintf 确保终止空字符适合提供的缓冲区大小,但 strncpy 不适合。
      • 不是标准 C,但您可以使用 strlcpy。确保始终包含 nul。
      猜你喜欢
      • 2016-07-13
      • 2016-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多