[英]Stack overflow correction in C++
我读了一本书中的以下代码,该代码很容易出现堆栈溢出。 尽管使用了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");
}
在display
tmp
声明为16个char
长,但是您正在写(使用sprintf
)不仅有val
(保证为16个字符或更少),而且还有"read val: "
和最后的\\n
。
这意味着,如果用户插入的字符超过16-11 = 5个字符,则display
会出现缓冲区溢出。
一种解决方案可能是声明display
buf
足够大,可以存储val
和其他文本,尽管在现实世界中,您只需要使用printf
向stdout
写入即可(无需中间缓冲区)。
另外,通常,当您有sprintf
且存在缓冲区溢出的潜在风险时,请改用snprintf
(实际上,我始终使用); snprintf
不会溢出缓冲区,而是将其截断(如果输出的长度太长),并返回如果输出缓冲区足够大的情况下应写入的字符数。
在显示中,无法确定val + 12个字节是否适合16个字符的缓冲区。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.