1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 避免缓冲区溢出的方法

避免缓冲区溢出的方法

时间:2019-02-18 22:36:59

相关推荐

避免缓冲区溢出的方法

缓冲区溢出一般是由于一下原因导致:

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,关于安全函数请看/library/wd3wzwts.aspx

6.检查文件路径的长度,不要超过系统允许的最大值。

相关工具:

1.静态检查工具:Klocwork,Intel Compiler

2.动态检查工具:PageHeap,Valgrind

3.MS Compiler:

(1)缓冲区安全检查:/GS

(2)数据执行保护(compatibility with data execution protection):/NXCOMPAT。具体参见:/cumt_xl/blog/static/1907150448411411326/

(3)安全的异常处理:/SAFESEH。具体参见:/magictong/article/details/7517630

4.GCC Compiler:

(1)gcc -fstack-protector 具体参见:/developerworks/cn/linux/l-cn-gccstack/

(2)ld -pie (gcc -fPIE),这个需要内核支持ASLR,具体参见:/apxar/article/details/10366649

(3)gcc -D_fortify_source=2 -O2,编译时检查和运行时检查,格式化字符串%n将被禁止。

(4)gcc -Wformat -Wformat-security,检查格式化类型

---------------------

作者:penngrove

来源:/penngrove/article/details/48466249

缓冲区溢出(buffer overflow)避免方法

什么是缓冲区溢出?

copy数据进buffer时,数据长度超过buffer中的剩余空间。

缓冲区溢出的危害?

缓冲区溢出,结果随机,可能会导致程序功能不正常,也可能导致程序崩溃。如果受到影响的是其它功能,因为故障现象随机,所以问题通常很难定位。别有用心的攻击者还会利用缓冲区溢出缺陷,覆盖控制变量的内容,接管程序的运行。

详细来说:

读越界时,因为读取到错误的数据,所以可能导致功能不正常,也可能导致程序崩溃。写越界时,如果后面的内存存放着应用程序的数据,则会导致其它功能读取到错误的数据,其它功能因此工作不正常,也可能导致程序崩溃。写越界时,如果后面的内存被用于程序运行的控制,则影响程序的运行,别有用心的黑客可以利用这一点实现程序的接管。写越界时,如果后面的内存没有在使用,则没有明显影响。

如何防止缓冲区溢出?

不能使用strcpy()、sprintf()等不安全的函数,而要在strncpy()、memcpy()、snprinf()的基础上封装出安全的函数,对copy进buffer的内容大小进行限制,超过大小则截断。

在strncat的基础上封装安全的函数:

char *strncat_s(char *dest, const char *src, size_t n,size_t total_buf_size){

/*如果buffer溢出,则截断,copy满为止,减1是为了存放字符串结束标志*/

if(strlen(dest)+n>total_buf_size-1){

n=total_buf_size-1-strlen(dest);

}

return strncat(dest, src, n);

}

类似的,在memcpy基础上封装安全的函数:

void *memcpy_s(void *dest, const void *src, size_t n, size_t left_buf_size){

/*如果buffer溢出,则截断,copy满为止*/

if(n> left_buf_size){

n= left_buf_size;

}

return memcpy (dest, src, n);

}

注意:我们通常不会记录buffer还剩余多少字节的空间,但是我们知道buffer的总大小和已经使用的大小,前者-后者就得到了剩余空间。

除非是性能要求非常高的地方,否则使用安全函数。比如多核CPU路由器转发平面C代码,性能要求很高,逻辑是一条线,非常清晰可控,所以不需要使用安全函数。路由器控制平面代码功能复杂,buffer溢出的可能性很难杜绝,性能要求相对较低,所以都使用安全函数。

读buffer时如果指针偏移量+要读的字段大小>buffer总大小,则会发生读溢出,但是这种溢出相比于写溢出好定位很多。因为读buffer的功能会失效。所以代码中不需要再做额外的安全性检查。

---------------------

作者:jxzdsw

来源:/jxzdsw/article/details/81178010

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。