C ++中的堆栈溢出校正

时间:2012-11-05 01:39:00

标签: c++ stack-overflow

我在一本书中读到了下面的代码,该书说这很容易受到堆栈溢出的影响。虽然已经使用了fgets(),但我无法理解为什么它容易受到攻击?

我的理解是使用fgets()而不是gets()通常可以通过在末尾放置null来帮助我们摆脱缓冲区溢出。我错过了什么吗?应该使用什么来代替fgets()来纠正堆栈溢出?

void getinp(char *inp, int siz)
{
   puts("Input value: ");
   fgets(inp, siz, stdin);
   printf("buffer3 getinp read %s\n", inp);
}

void display(char * val)
{
   char tmp[16];
   sprintf(tmp, "read val: %s\n", val);
   puts(tmp);
}

int main(int argc, char *argv[])
{
   char buf[16];
   getinp(buf, sizeof(buf));
   display(buf);
   printf("buffer3 done\n");
}

2 个答案:

答案 0 :(得分:1)

display tmp被宣布为16 char s长,但您正在撰写(sprintf)不仅val(这是"read val: "保证不超过16个字符),但\n和最终display)。

这意味着如果用户插入超过16-11 = 5个字符,则buf中的缓冲区溢出。

一个解决方案可能是声明display中的val足够大以存储stdout和其他文本,尽管在现实世界中您只需写入printf使用sprintf(没有中间缓冲区)。

此外,通常当你有snprintf并且存在缓冲区溢出的潜在风险时,你可以使用snprintf代替(实际上,我使用它总是); {{1}},而不是溢出缓冲区,如果输出太长则截断输出,并返回如果输出缓冲区足够大就会写入的字符数。

答案 1 :(得分:0)

在显示中,无法确定val + 12字节是否适合16个字符的缓冲区。