当前位置:编程学习 > 网站相关 >>

[译]CERT Secure Coding Standard — C语言安全编程规范(2)

04. 整数

规则/建议条目全称 例外 笔记 /备注/点评
INT00-C. 理解你的代码实现中的数据模型
数据模型定义了标准数据类型的存储空间大小。如char在几乎所有的平台下的实现都是8字节长度,long在IA-32/64都是32字节,但在64-bit Linux/*BSD下是64字节。因此,当程序需要跨多个应用平台运行时需要考虑数据模型的实现差异可能对程序运行中的一些“假设”前提条件的影响。
INT01-C. 使用rsize_t或者size_t来表示一个对象所占用空间的整数值单位
size_t的最大值由SIZE_MAX宏定义,一般情况下size_t能够覆盖所有可用的地址空间数值表示范围。ISO/IEC TR 24731-1-2007标准中引入了一个新的数据类型rsize_t,定义为size_t但显式的用于表示一个单个对象的大小。支持rsize_t的代码,可以使用RSIZE_MAX来判断一个单个对象的大小不超过RSIZE_MAX(一个正常单个对象的内存占用的最大值),库函数可以使用rsize_t来进行输入校验。
INT02-C. 理解整数转换规则
整数的转换可能发生在显式的加法运算过程中或者是某些运算符的要求,对于整数的转换规则来说特别需要注意有符号整数和无符号整数之间的转换规则,除此之外就是和整数的“转换等级”相邻的数据类型和整数之间的相互转换规则。
INT03-C. 使用一个安全的整数库

对抗整数类漏洞的第一道防线是数据有效范围检测,特别是当输入参数个数较多、进行大数运算时,整数类漏洞是最容易被触发的。具体来说,以下是最常见的整数类漏洞发生场景:
1. 数组的下标
2. 指针运算
3. 对象的长度或大小
4. 数组的边界值(例如,循环中的计数器)
5. 内存分配函数的参数
6. 关键安全代码
CERT/CC为Windows平台提供了一个IntegerLib。

INT04-C. 强制限来自不安全(输入)源的整数值大小
INT05-C. 如果无法处理所有可能的输入值时禁止使用输入函数来转换字符数据 例如格式化输入函数,如scanf(), fscanf(), vscanf(), vfscanf()被用于读取来自标准输入或者(仅限于fscanf(), vfscanf())其他输入流的字符数据时是安全的。这些函数对合法的整数值范围输入是可以正常处理的但非法值的处理能力不够强健。
以Linux平台的scanf()函数为例,如果对于输入的整数数据的“格式化”转换结果无法使用提供的格式化字符串来存储时,scanf()会设置错误变量errno为ERANGE。需要注意的是,检查errno是否等于ERANGE的方法在Linux平台上是可行的,但并不保证在其他平台上也一定可行。只有在不需要考虑平台移植性的前提条件下,才可以使用这个方法。
INT06-C. 使用strtol()或者其他相关函数来转换一个字符标记串为一个整数 strtol()系列函数被设计用来替换如下不安全的“等效”函数

atoi: (int)strtol(nptr, (char **)NULL, 10)
atol: strtol(nptr, (char **)NULL, 10)
atoll: strtoll(nptr, (char **)NULL, 10)
INT07-C. 使用显式的有符号或无符号字符类型来表示数值 INT07-EX1: 规则FIO34-C. Use int to capture the return value of character IO functions中提到某些字符IO函数的返回值是int。尽管返回值是算术类型,但本质上返回值并不是数值类型,因此可以使用char类型来存储这一类函数的返回值。
Note: char, signed char, unsigned char被统称为字符类型。但char和其他两种字符类型是不相互兼容的,因此在需要使用字符类型表示数值时必须要从signed char和unsigned char中二选一。

INT08-C. 验证所有整数值都在整数值的有效范围之内
最典型的一个例子就是MAX+1,如果加法的两个操作数都是unsigned int,且返回结果也是unsigned int来存储,则根据C标准,其结果将是MIN。而这在绝大多数的应用场景显然是一种错误的“逻辑”,很多情况下,MAX+1我们期待返回的值是MAX,而不是MIN。
INT09-C. 确保枚举类型常量被映射为唯一值 INT09-EX1:类似以下代码:

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,