如果我错了,请纠正我,我在网站上研究,但找不到任何有关此问题的综合帖子。 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;
}
答案 0 :(得分:4)
strncpy
不是strcpy
的安全替代品。实际上,尽管命名中存在不幸的相似性,但这些功能是无关的。 strcpy
的安全替换是由某些* nix实现作为扩展提供的非标准函数strlcpy
。 strncpy
用于&#34;安全&#34;字符串复制是无能代码的直接标志。
另一组不安全的函数(虽然因其他原因而不安全)是来自ato..
组的函数:atoi
,atof
,atol
等等。这些函数在溢出时触发未定义的行为。他们的安全替换是strto...
组的功能:strtol
,strtod
等。
没有什么&#34;不安全&#34;关于copy_buf
函数,它在某种意义上为调用代码提供了执行copy_buf
安全调用所需的一切手段。在这种情况下传递正确值的责任放在调用者身上。
你的read_chunk
函数更危险,因为调用代码无法知道缓冲区应该有多大。对于这个函数来说,没有完美的解决方案可以很好地处理从外部传递的缓冲区。至少使调用代码也传递缓冲区的大小是有意义的。这将允许read_chunk
确保缓冲区没有溢出。此外,read_chunk
应该通知调用代码有关不完整的读取。您应该为呼叫者提供完成阅读的方法。
答案 1 :(得分:3)
以下是一些不安全的C函数列表及其替换的新函数
无论如何使用,某些功能都会以危险的方式运行。通常在不考虑安全问题的情况下实施此类别中的功能。 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 ++中的危险的更多内容..
答案 2 :(得分:2)
(char *dest, size_t destsize, const char *format, ...).
你必须给出目的地和目的地的最大尺寸\0
。所以它不会写在dest[destsize - 1]
上面。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标准中删除的原因。