用这个代码片段有可能是错误的(在软件安全性方面),我似乎无法弄清楚......函数在显示字符串参数后终止程序。c代码片段中的安全缺陷?
void get_user(char* user)
{
char buf[1024];
if (strlen(user) > sizeof(buf))
die("error: user string too long\n");
strcpy(buf, user);
…
}
-thx!
用这个代码片段有可能是错误的(在软件安全性方面),我似乎无法弄清楚......函数在显示字符串参数后终止程序。c代码片段中的安全缺陷?
void get_user(char* user)
{
char buf[1024];
if (strlen(user) > sizeof(buf))
die("error: user string too long\n");
strcpy(buf, user);
…
}
-thx!
它不计算NUL(\0
)终止的字符串。
if (strlen(user) >= sizeof(buf))
这是不安全的,如果user
有1024个字符(会写0
某处在堆栈上)。
尽管'strlen(user)+ 1'的病态实现可能会溢出,原则上最好使用'> ='运算符而不是加法来避免数值溢出问题。 –
@R ..这很有趣;你能详细了解溢出问题吗? – cnicutar
'strlen(user)+ 1'不能溢出,因为字符串对象的实际大小包含空终止符。但是,假设你想知道'size1'和'size2'的对象是否可以放在一个缓冲区中。 'if(size1 + size2> available)'不是一个正确的测试,因为添加大小可能会换行(如果它们是未签名的)或溢出并给予UB(如果它们是已签名的)。因此,至少在我看来,这种形式的条件是*代码气味* - 它们表明潜在的安全缺陷,并需要进一步阅读以确定代码是否实际上是安全的。 –
如果strlen(user)
等于1024,strcpy
将在buf
的末尾写入一个字节。
的问题是在这里:
if (strlen(user) > sizeof(buf))
这并不占空终止时strlen(user) == sizeof(buf)
。该检查应
if (strlen(user) > sizeof(buf) - 1)
使strcpy()
可以随时复制空终止。
有一个可能导致缓冲区溢出的错误的错误。请记住,strlen会为您提供字符串中的字符数,,不包括空终止符。检查应该是:
if (strlen(user) + 1 > sizeof(buf))
从strlen的手册页:
所述的strlen()函数计算的字符串s的长度,不 包括终止 '\ 0' 字符。
并从strcpy的手册页:
的的strcpy()函数将字符串由src指出,包括 终止空字节( '\ 0'),到缓冲区指向DEST。
尺寸比较存在不匹配。代码检查字符串长度是否小于缓冲区,但复制字符串长度为+1个字符。如果字符串长度(小于终止'\ 0')为1024,则会发生溢出。
这功课吗? – Skizz