缓冲区溢出一般是由于一下原因导致:
1.字符串处理函数没有指定长度,单单凭借结尾字符是不是'\0'来判断结束。
2.被处理的字符超过缓冲区可接受的大小。例如,从屏幕输入字符串:gets(buff),但是buff的内存少于屏幕一行字符个数,就会导致溢出,应该使用fgets。
3.所有格式化字符串的函数:fprintf("%n",&num_write)。
避免的办法:
1.不要用%n formatter
2.不要把用户的输入作为参数传到格式化字符串处理函数中,例如,printf("%s", argv[1])。
3.字符串处理避免使用strcpy,strcat,sprintf,gets。应该使用strncpy,strncat,snprintf。strlcpy和strlcat都是NULL结尾。尽量使用std::string,MFC::CString
4.使用C++ I/O函数
5.使用安全的C Runtime Time函数*_s function,关于安全函数请看https://msdn.microsoft.com/library/wd3wzwts.aspx
6.检查文件路径的长度,不要超过系统允许的最大值。
相关工具:
1.静态检查工具:Klocwork,Intel Compiler
2.动态检查工具:PageHeap,Valgrind
3.MS Compiler:
(1)缓冲区安全检查:/GS
(2)数据执行保护(compatibility with data execution protection):/NXCOMPAT。具体参见:http://blog.163.com/cumt_xl/blog/static/19071504420138411411326/
(3)安全的异常处理:/SAFESEH。具体参见:http://blog.csdn.net/magictong/article/details/7517630
4.GCC Compiler:
(1)gcc -fstack-protector 具体参见:http://www.ibm.com/developerworks/cn/linux/l-cn-gccstack/
(2)ld -pie (gcc -fPIE),这个需要内核支持ASLR,具体参见:http://blog.csdn.net/apxar/article/details/10366649
(3)gcc -D_fortify_source=2 -O2,编译时检查和运行时检查,格式化字符串%n将被禁止。
(4)gcc -Wformat -Wformat-security,检查格式化类型
---------------------
作者:penngrove
来源:https://blog.csdn.net/penngrove/article/details/48466249