0

我在一本书中读到下面的代码,它说这很容易受到堆栈溢出的影响。虽然使用了 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");
}
4

2 回答 2

1

Indisplay tmp被声明为 16 chars 长,但你正在写(使用sprintf)不仅val(保证为 16 个字符或更少),而且还有"read val: "final \n)。

这意味着如果用户插入超过 16-11=5 个字符,您的display.

一种解决方案可能是声明bufindisplay足够大以存储val额外的文本,尽管在现实世界中您只需写入stdoutusing printf(没有中间缓冲区)。

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

于 2012-11-05T01:43:57.363 回答
0

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

于 2012-11-05T01:42:44.053 回答