Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c代码段中的安全漏洞?_C_Security - Fatal编程技术网

c代码段中的安全漏洞?

c代码段中的安全漏洞?,c,security,C,Security,这段代码可能有错误(在软件安全方面),我似乎无法理解…函数die在显示字符串参数后终止程序 void get_user(char* user) { char buf[1024]; if (strlen(user) > sizeof(buf)) die("error: user string too long\n"); strcpy(buf, user); … } -谢谢 答案与chars strpy拷贝数与chars strlen返回数的比较有关 提示:,它不计

这段代码可能有错误(在软件安全方面),我似乎无法理解…函数die在显示字符串参数后终止程序

void get_user(char* user)
{
  char buf[1024];
  if (strlen(user) > sizeof(buf))
    die("error: user string too long\n");
  strcpy(buf, user);
  …
} 

-谢谢

答案与chars strpy拷贝数与chars strlen返回数的比较有关


提示:,

它不计算字符串的NUL(
\0
)终止符

if (strlen(user) >= sizeof(buf))
如果
user
有1024个字符(将
0
写入堆栈的某个位置),则不安全

如果
strlen(user)
等于1024,
strcpy
将在
buf
末尾写入一个字节,问题在于:

if (strlen(user) > sizeof(buf))
strlen(user)==sizeof(buf)
时,这不考虑空终止符。支票应该是

if (strlen(user) > sizeof(buf) - 1 )

因此,
strcpy()
可以随时复制空终止符。

存在一个off by one错误,可能导致缓冲区溢出。请记住,strlen提供字符串中的字符数,不包括空终止符。支票应为:

if (strlen(user) + 1 > sizeof(buf)) 

从strlen手册页:

函数的作用是:计算字符串s的长度,而不是 包括终止字符“\0”

从strcpy手册页:

函数的作用是:复制src指向的字符串,包括 终止dest指向的缓冲区的空字节('\0')


大小的比较不匹配。代码检查字符串长度是否小于缓冲区,但复制字符串长度+1个字符。如果字符串长度(小于终止'\0')为1024,则会发生溢出。

虽然要使
strlen(user)+1
能够溢出需要病态的实现,但原则上,在进行此类测试时,最好使用
=
运算符,而不是加法,以避免出现数字溢出问题。@R。。这很有趣;您可以详细说明溢出问题吗?嗯
strlen(user)+1
无法溢出,因为string对象的实际大小包括null终止。但是,假设您想知道
size1
size2
的对象是否可以一起放入缓冲区
if(size1+size2>可用)
不是正确的测试,因为添加大小可能会换行(如果未签名)或溢出并给出UB(如果已签名)。因此,至少在我看来,这种形式的条件句是一种代码味道——它们表示潜在的安全缺陷,需要进一步阅读以确定代码是否真正安全。@R。。谢谢你的解释,这很合理:-)