C 这容易受到堆栈溢出的攻击吗?
从我所读到的内容来看,当您想要限制输入的大小时,应该使用fgets。所以这段代码不应该有漏洞,对吗 人们这样称呼它:C 这容易受到堆栈溢出的攻击吗?,c,stack,overflow,C,Stack,Overflow,从我所读到的内容来看,当您想要限制输入的大小时,应该使用fgets。所以这段代码不应该有漏洞,对吗 人们这样称呼它: void gctinp (char *inp, int siz) { puts ("Input value: "); fgets (inp, siz, stdin); printf ("buffer3 getinp read %s", inp); } 感谢您的时间。fgets读取的字节数最多比指定的字节数少一个,并且将确保读取字符串以null结尾。因此,只要传递正
void gctinp (char *inp, int siz)
{
puts ("Input value: ");
fgets (inp, siz, stdin);
printf ("buffer3 getinp read %s", inp);
}
感谢您的时间。fgets读取的字节数最多比指定的字节数少一个,并且将确保读取字符串以null结尾。因此,只要传递正确的大小,就可以了,尽管字符串可能不会以换行符结尾。fgets读取的字节数最多比指定的字节数少一个,并确保读取的字符串以null结尾。因此,只要传递正确的大小,就可以了,尽管字符串可能不会以换行符结尾。不,它不容易出现堆栈溢出 您是否碰巧混淆了堆栈溢出和缓冲区溢出
不,它不容易出现堆栈溢出 您是否碰巧混淆了堆栈溢出和缓冲区溢出
如果输入的字符超过安全存储的字符数,则不会出现缓冲区溢出问题,因为fgets限制输入。当然,它还添加了一个空终止符,假设缓冲区大小大于0 但是,当您下次尝试读取某些内容时,您会遇到信息留在输入缓冲区中的问题-这是用户会觉得非常烦人的事情,再次输入类似hello的内容,并将其作为两个单独的输入,例如hello ag和ain。fgets并没有给出它在行尾之前停止检索输入的指示,所以,就您的代码所知,一切都很好 您需要注意的主要问题是输入上的重新缓冲区溢出至少是scanf,它带有一个无界的%s格式字符串和get,它没有限制大小的参数,这两个参数都不在您的代码中 如果您正在寻找具有大小限制、提示和缓冲区清除功能的更健壮的输入解决方案,请查看此代码,它提供了所有这些功能:
int main (int argc, char *argv[])
{
char buf[16];
getinp (buf, sizeof (buf));
display (buf);
printf ("buffer3 done\n");
}
进行一些基本测试:
// Test program for getLine().
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
rc = getLine ("Hit ENTER to check remains> ", buff, sizeof(buff));
printf ("Excess [%s]\n", buff);
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
如果输入的字符超过安全存储的字符数,则不会出现缓冲区溢出问题,因为fgets限制输入。当然,它还添加了一个空终止符,假设缓冲区大小大于0 但是,当您下次尝试读取某些内容时,您会遇到信息留在输入缓冲区中的问题-这是用户会觉得非常烦人的事情,再次输入类似hello的内容,并将其作为两个单独的输入,例如hello ag和ain。fgets并没有给出它在行尾之前停止检索输入的指示,所以,就您的代码所知,一切都很好 您需要注意的主要问题是输入上的重新缓冲区溢出至少是scanf,它带有一个无界的%s格式字符串和get,它没有限制大小的参数,这两个参数都不在您的代码中 如果您正在寻找具有大小限制、提示和缓冲区清除功能的更健壮的输入解决方案,请查看此代码,它提供了所有这些功能:
int main (int argc, char *argv[])
{
char buf[16];
getinp (buf, sizeof (buf));
display (buf);
printf ("buffer3 done\n");
}
进行一些基本测试:
// Test program for getLine().
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
rc = getLine ("Hit ENTER to check remains> ", buff, sizeof(buff));
printf ("Excess [%s]\n", buff);
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
我认为您混淆了堆栈溢出和缓冲区溢出。堆栈溢出问题最常见的原因是递归函数多次调用自身而不返回。是的,aschepler所说的是正确的,但另外,堆栈上可能发生缓冲区溢出。如果您使用了gets,它将容易受到堆栈上缓冲区溢出的攻击,而不是堆栈溢出。我认为您混淆了堆栈溢出和缓冲区溢出。堆栈溢出问题最常见的原因是递归函数多次调用自身而不返回。是的,aschepler所说的是正确的,但另外,堆栈上可能发生缓冲区溢出。如果您使用了gets,它将容易受到堆栈缓冲区溢出的攻击,而不是堆栈溢出。。不可以。只要提供的大小至少为1,fgets always nul将终止结果。抱歉,应该使该大小必须足够大,以容纳终止符,否则它在第一段中存储不清楚-已修复。错误。。否。只要提供的大小至少为1,fgets总是nul终止结果。抱歉,应该使该大小必须足够大,以容纳终止符,否则它在第一段中存储不清楚-已修复。