不安全的C功能和更换

时间:2014-10-25 00:39:15

标签: c

如果我错了,请纠正我,我在网站上研究,但找不到任何有关此问题的综合帖子。 C中有许多不安全的函数可能导致缓冲区溢出,并且它们具有替换它们的安全功能。我有几个:

  • gets() ===替换为=== fgets()
  • sprintf() ===替换为===?
  • strcat() ===替换为===?
  • strcpy() ===替换为=== strncpy()
  • vsprintf() ===替换为=== vsnprintf()

另外,我坚持下面的不安全字节拷贝和不安全的字节输入代码。我该如何解决这些问题? 为什么这段代码有漏洞?

int copy_buf (char *to, int pos, char *from, int len)
{
    int i;
    for (i=0;i<len;<i++){
         to[pos] = from [i];
         pos++;
    }
    return pos
}

对于字节输入,是fread()不安全的函数吗?为什么缓冲区溢出发生在这里?

short read_chunk(FILE fil, char *to)
{
    short len;
    fread(&len, 2, 1, fil);
    fread(to, 1, len, fil);
    return len;
}

5 个答案:

答案 0 :(得分:4)

strncpy strcpy的安全替代品。实际上,尽管命名中存在不幸的相似性,但这些功能是无关的。 strcpy的安全替换是由某些* nix实现作为扩展提供的非标准函数strlcpystrncpy用于&#34;安全&#34;字符串复制是无能代码的直接标志。

另一组不安全的函数(虽然因其他原因而不安全)是来自ato..组的函数:atoiatofatol等等。这些函数在溢出时触发未定义的行为。他们的安全替换是strto...组的功能:strtolstrtod等。

没有什么&#34;不安全&#34;关于copy_buf函数,它在某种意义上为调用代码提供了执行copy_buf安全调用所需的一切手段。在这种情况下传递正确值的责任放在调用者身上。

你的read_chunk函数更危险,因为调用代码无法知道缓冲区应该有多大。对于这个函数来说,没有完美的解决方案可以很好地处理从外部传递的缓冲区。至少使调用代码也传递缓冲区的大小是有意义的。这将允许read_chunk确保缓冲区没有溢出。此外,read_chunk应该通知调用代码有关不完整的读取。您应该为呼叫者提供完成阅读的方法。

答案 1 :(得分:3)

以下是一些不安全的C函数列表及其替换的新函数

  • strcpy - &gt; strncpy - &gt;是strlcpy / strcpy_s
  • strcat - &gt; strncat - &gt; strlcat提供/ strcat_s -strtok
  • sprintf - &gt;的snprintf
  • vsprintf - &gt; vsnprintf
  • 获取 - &gt;与fgets / gets_s
  • makepath - &gt; _makepath_s(MSDN)
  • _splitpath - &gt; _splitpath_s(MSDN)
  • scanf / sscanf - &gt; sscanf_s(MSDN)
  • snscanf - &gt; _snscanf_s(MSDN)
  • strlen - &gt; strnlen_s(MSDN)

无论如何使用,某些功能都会以危险的方式运行。通常在不考虑安全问题的情况下实施此类别中的功能。 gets()函数是不安全的,因为它不对其输入的大小执行边界检查。

攻击者可以轻松地将任意大小的输入发送到gets()并溢出目标缓冲区。同样,&gt;&gt;读取静态分配的字符数组时,运算符是不安全的,因为它不会对其输入的大小执行边界检查。攻击者可以轻松地将任意大小的输入发送到&gt;&gt;运算符并溢出目标缓冲区。

下面的代码调用gets()将信息读入缓冲区。

char buf[24];
printf("Please enter your name and press <Enter>\n");
gets(buf);
...
}

然而,程序员使用本身不安全的函数gets(),因为它盲目地将所有输入从STDIN复制到缓冲区而不检查大小。这允许用户提供大于缓冲区大小的字符串,从而导致溢出条件

你可以在这里进一步阅读有关C / C ++中的危险的更多内容..

  1. http://www.dwheeler.com/secure-class/Secure-Programs-HOWTO/dangers-c.html
  2. http://www.dwheeler.com/secure-programs/
  3. http://courses.cs.washington.edu/courses/cse341/04wi/lectures/26-unsafe-languages.html

答案 2 :(得分:2)

  • sprintf ===替换为=== snprintf:因为你必须像这样使用snprintf (char *dest, size_t destsize, const char *format, ...).你必须给出目的地和目的地的最大尺寸\0。所以它不会写在dest[destsize - 1]上面。
  • strcat ===替换为=== snprintf:见上文
int copy_buf (char *to, int pos, char *from, int len)

此方法不安全,因为您对两个char指针都使用len。也许会出现分段错误,因为你的for循环可以超出指针之一。最好为每个指针使用两个变量。

答案 3 :(得分:1)

sprintf => snprintf
strcat => strncat

答案 4 :(得分:1)

列出的唯一不安全功能是gets(),因为它引入的不确定性无法在 * 1 周围进行操作。

如果使用正确,所有其他功能都是安全的。


* 1这就是它从C标准中删除的原因。