C/C++中库的解决方案 |
|
|
C/C++中的一个解决方案是使用没有缓存溢出问题的库函数。第一小节描述了“标准C库”的解决方案,可以解决问题但存在不足之处。接下来描述了缓存的固定长度和动态重新分配方案的一般性安全问题。最后一个小节描述了各种替代库,如strlcpy和libmib。
标准C库的解决方案
C中防止缓存溢出的“标准”解决方案是使用可以防御这些问题的标准C库调用。该方案严重依赖于标准库函数strncpy(3)和strncat(3)。如果选择了该方案,要小心:这些调用的语义有些出人意料,难以正确使用。如果源字符串长度至少等于目标字符串的长度,函数strncpy(3)就不会用NIL来终止目标字符串,所以要在调用strncpy(3)之后要确定目标字符串的最后一个字符被设置为NIL。如果要多次重复使用同一个缓存,一个有效的方法是告诉strncpy()该缓存比其实际长度短一个字符,并在使用之前把最后一个字符设置为NIL。strncpy(3)和strncat(3)都要求传递可用的剩余空间大小,这是容易出错的一个计算(计算错误会允许缓存溢出攻击)。这二者都没有提供一个简单的机制来确定是否发生了溢出。最后,与要替代的strcpy(3)相比,strncpy(3)还会带来相当大的性能下降,因为strncpy(3)要用NIL填满目标的剩余空间。我收到一些email,对最后这一点表示惊奇,但这在Kernighan和Ritchie第二版[Kernighan 1988, page 249]中明确说明过,而且在Linux、FreeBSD和Solaris的man帮助页上对此行为也有明确说明。这就意味着仅仅把strcpy换成strncpy可以导致严重的性能降低,在大多数情况下没有什么很好的理由。
静态和动态分配缓存
strncpy及其友好函数是静态分配缓存的一个例子,也就是说,一旦缓存被分配,其大小就是固定的。其替代方法就是在需要的时候动态重新分配缓存大小。而结果表明两种方案都有安全性隐患。
在使用固定长度缓存有个一般性的安全问题:缓存长度固定这一事实可能被利用。这是与strncpy(3)和strncat(3)、snprintf(3)、strlcpy(3)、strlcat(3)以及其它此类函数有关的问题。其基本思想是攻击者建立一个确实很长的 < 1 > < 2 > |
|
|
在百度搜索:C/C++中库的解决方案
|