软件编程低级错误:内存越界ppt课件

上传人:资****亨 文档编号:145747438 上传时间:2020-09-23 格式:PPT 页数:43 大小:262KB
返回 下载 相关 举报
软件编程低级错误:内存越界ppt课件_第1页
第1页 / 共43页
软件编程低级错误:内存越界ppt课件_第2页
第2页 / 共43页
软件编程低级错误:内存越界ppt课件_第3页
第3页 / 共43页
软件编程低级错误:内存越界ppt课件_第4页
第4页 / 共43页
软件编程低级错误:内存越界ppt课件_第5页
第5页 / 共43页
点击查看更多>>
资源描述

《软件编程低级错误:内存越界ppt课件》由会员分享,可在线阅读,更多相关《软件编程低级错误:内存越界ppt课件(43页珍藏版)》请在金锄头文库上搜索。

1、公司常见软件编程低级错误:内存越界,C语言软件编程规范工作组,前言,这套材料作为编程规范的辅助材料,帮助大家理解编程规范背后的原理。 C和C+语言是我司的主流编程语言,然而C/C+具有很多强大的语言特性,从而导致C/C+非常复杂,使得代码更容易出现BUG、难以阅读和维护。 业界知名的编程规范都对C/C+容易出现问题的语言特性进行管理。例如MISRA(汽车工业软件可靠性联合会)制定的1998版的MISRAC规范指出,一些在C看来可以接受,却存在隐患的地方有127处之多。2004版的MISRAC规范将针对C语言的规则增加到了141条。 对于程序员来说,能工作的代码并不等于“好” 代码。“好”代码的

2、指标很多,包括可读性、可维护性、可移植性和可靠性等。出现网上问题的代码,大多数是不良编程习惯引起的。不遵守编程规范的代码,往往也是最不可靠的代码。 本胶片收集了常见的内存越界案例,给出了相应的纠正措施。对应的编程规范:防止内存操作越界,常见的内存越界问题和解决措施建议,数组分配未考虑最大情况,导致空间不够,【问题描述】透明消息下发处理导致网上单板复位 【问题定位】当消息发送失败后的异常处理流程中,存在局部数据越界,导致别的任务在使用错误的堆栈信息时,发生数据访问异常,而单板复位。 UINT8 aucErrMsg128 = 0; /* 用于返回错误信息字符串*/ ulRet = VOS_Send

3、Msg(pMsgBlock); if ( VOS_OK != ulRet ) VOS_sprintf(CHAR *)aucErrMsg, rn DBG_SimExternalMsgAct: VOS_SendMsg fail!ulRet(%u), ulSenderCpuId(0 x%x), ulSenderPid(%u), ulReceiverCpuId(0 x%x), ulReceiverPid(%u), ulRet, pMsgBlock-ulSenderCpuId, pMsgBlock-ulSenderPid, pMsgBlock-ulReceiverCpuId, pMsgBlock-ulR

4、eceiverPid); %u输出的十进制无符号整数,范围04294967295,长度111位不定,随着程序的运行,数值会越来越大,从1位数变成2位数,3位数,11位数等,导致内存越界。同样%x的长度最大可以达到8位。 aucErrMsg的长度最大应该为:120(字符长度)+3*11(3个无符号整数长度%u)+2*8(2个十六进制整数长度%x)169,不是128. 【纠正措施】将数组aucErrMsg大小定义扩大为256 。 【举一反三】数组的大小要考虑最大情况,避免数组分配空间不够。,数组分配未考虑最大情况,导致空间不够(续一),【问题描述】实时性能统计,可选指标达到最大,单击保存设置,造成

5、网管实时性能后台重启 【问题定位】代码的数组长度为256字节,当选择满20个指标时,字符串长度为276个,造成栈空间越位。 【纠正措施】C语言:把字符串缓冲区改正1024个字节长度;C+:使用相应的类库std:string等。 【举一反三】多大的缓冲区才是安全的?对C来说,要考虑到各种应用场合,特别是考虑到函数参数的边界条件,按最大的可能分配空间。能够程序计算的,尽量自动计算。对C+而言,不要使用C语言风格的数组、指针运算和内存管理原语操作实现数组,使用vector或者string,请把这种复杂的体力劳动交给类库吧 !,数组分配未考虑最大情况,导致空间不够(续二),【问题描述】数据库刷新间隔设

6、为值1073741823时,系统监控后台coredump,监控前台抛异常。 【问题定位】使用itoa()将整型数转换为字符串时: char szTempShold10 ; itoa(usProcFrecy,szTempShold,10); szTempShold是以0结尾的字符数组,只能存储9个字符,而usProcFrecy的最大值可达到10位,导致符数组szTempShold越界。 【纠正措施】将数组设置成12位 【举一反三】按最大的可能分配空间,一个int(32位)在21474836472147483648之间,使用itoa函数安全的分配空间是12位。,使用危险函数操作字符串,【问题描述】

7、发送短消息的时候进程COREDUMP 【问题定位】使用了一个1024个字节的字符数组进行sprintf格式化操作,当告警发送数量比较大,写入日志的字符串很长,内存越界 【纠正措施】将sprintf替换成安全函数snprintf,指定缓冲区大小,确保内存不会越界 【举一反三】 C语言提供的字符串库函数sprintf /vsprintf/strcpy/strcat/gets等非常危险,很容易导致内存越界,应该使用安全的字符串库函数snprintf/strncpy/strncat/fgets,指定操作的内存大小。 对C语言,应该使用相应的类库如std:string,std:stringstream,

8、 boost:lexical_cast操作字符串,而不要直接调用C语言的字符串函数。,使用危险函数操作字符串(续1),【问题描述】代码飞检时发现如下代码: char pszInfoBuf250; sprintf(pszInfoBuf,”* File:%s Line:%d *”,_FILE_,_LINE_); 【问题定位】 “_FILE_”在预编译时,被编译时的目录名和源文件名代替,但目录和文件名的长度可变,很可能超出250个字节,导致内存越界 【纠正措施】将sprintf替换成安全函数snprintf,指定缓冲区大小,确保内存不会越界 snprintf(pszInfoBuf,INFOBUF_S

9、IZE -1,”* File:%s Line:%d *”,_FILE_,_LINE_); pszInfoBufINFOBUF_SIZE -1=0;,使用危险函数操作字符串(续2),【问题描述】代码飞检时发现如下代码: char pszInfoBuf32; strcpy(pszInfoBuf,pMsg); 【问题定位】定义的pszInfoBuf共32字节,pMsg是从网络上接收的数据包,可能超出32个字节,导致内存越界 【纠正措施】将strcpy替换成安全函数strncpy ,指定缓冲区大小,确保内存不会越界 strncpy(pszInfoBuf,pMsg, INFOBUF_SIZE - 1);

10、 pszInfoBufINFOBUF_SIZE - 1=0;,使用memcpy/memset没有判断长度,【问题描述】局有用户投诉访问不了WAP业务,现场维护人员重启模块后业务恢复正常。 【问题定位】对core文件分析, 确认如下代码导致内存越界: memcpy(vpstResBody-pcData, wbxml, wbxml_len); 其中vpstResBody-pcData分配的内存数为3270,wbxml_len是wbxml的长度,wbxml取决与用户输入的URL。由于没有判断长度,当页面内容中几个相对URL链接的页面,这里发生了越界。 【纠正措施】增加长度保护:长度少于或等于vpst

11、ResBody-pcData的长度; 【举一反三】使用memcpy/memset时一定要确保长度不要越界,使用memcpy/memset没有判断长度(续),【问题描述】代码飞检发现如下代码: char pDeviceID20; char pDefaultDeviceID80; /异常情况使用缺省设备ID memcpy(pDeviceID,pDefaultDeviceID,sizeof(pDefaultDeviceID); 【问题定位】pDefaultDeviceID的长度是80, pDeviceID长度是20,从而导致内存越界。 【纠正措施】修改pDeviceID长度,和pDefaultDev

12、iceID长度一致。由于是字符串拷贝,改用strncpy。 #define DEVICEID_LEN 80 char pDeviceIDDEVICEID_LEN ; char pDefaultDeviceIDDEVICEID_LEN ; strncpy (pDeviceID,pDefaultDeviceID, DEVICEID_LEN ); pDeviceIDDEVICEID_LEN-1=0; 【举一反三】使用memcpy/memset时一定要确保长度不要越界;注意memcpy/strncpy的区别,字符串没有考虑最后的0,【问题描述】在现场测试补丁版本时,用命令RMV VSBR删除V5用户,

13、导致主、备FCCU复位。 【问题定位】使用 memcpy拷贝内存,通过strlen获得原始内存的长度,但传入的原始内存虽然是字符,但结尾并没有0, 而strlen继续向后寻找,直到找到一个0,结果拷贝了很大一块内存,导致内存越界 【纠正措施】函数调用时,除了传入原始内存的指针外,增加一个参数表明内存的长度 【举一反三】有些产品在设计上将字符串作为一块内存进行处理,在函数之间传递UINT8*的指针,在传递过程中,很可能没有拷贝字符串结尾的0,所以在这种设计下必须禁止调用C语言提供的字符串函数,包括strlen/snprintf。这种指针不能作为字符串使用。,字符串没有考虑最后的0(续1),【问题

14、描述】版本升级,并使用配置台修改代理服务器配置数据,发送配置;来话可以进入排队机,但无法接入话务台,平台倒换重启等措施无效。 【问题定位】从版本3.2开始,cfgcprs.dll的解压缩接口输出的数据长度不包括末尾位置的0,配置台代码将其拷贝进系统数据区时,也没有添加0。通常情况下,系统数据区后面的内存全是0,但在极例外的异常情况下为非0,此时内存读越界,导致配置台把配置数据转换成字符串后出现了乱码,解析异常,丢失了VDN数据。 【纠正措施】在拷贝配置数据时强制添加0 【举一反三】产品处理配置数据的规则不明确,版本3.1将配置数据作为字符串处理,版本3.2中的cfgcprs.dll将配置数据作

15、为一块内存处理,但有的模块继续作为字符串处理。必须将处理规则明确写作在设计文档中。,字符串没有考虑最后的0(续2),【问题描述】代码飞检时发现如下代码: ulNewSize VOS_strlen(“rn”)+VOS_strlen(pRevData) + VOS_strlen(pszVlanInfo)+ VOS_strlen(pszQinQinfo); pszDisInfo = VOS_Malloc(MID_BVLAN, ulNewSize); . VOS_ strcat (pszDisInfo, pszQinQinfo); 【问题定位】以ulNewSize为长度申请内存,但忘记字符串结尾必须有

16、一个0,调用strcat时拷贝了字符串本身和最后的0,导致内存越界 【纠正措施】计算ulNewSize时,增加1个字节,字符串没有考虑最后的0(续3),【问题描述】代码飞检时发现如下代码 pszInfo = (CHAR*) VOS_Malloc( MID_CFM, ulSize); . pszInfoulSize = 0; 【问题定位】以ulSize为长度申请内存,作者最后想起来需要在字符串最后添加0,但边界值考虑不当。 【纠正措施】分配内存时,增加1个字节;或将赋值语句修改为pszInfoulSize - 1 = 0;,字符串没有考虑最后的0(续4),【问题描述】代码飞检时发现如下代码: pErrMsgBuffer = VOS_Malloc(MODULE_ID_MAPPERDRV, dwBufSize + 1); strncpy (pErrMsgBuffer, strErrMsg, dwBufSize); 【问题定位】当源字符串长度超出dwBufSize时,strncpy拷贝dwBufS

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号