CTR50-CPP. 保证容器索引和迭代器在有效范围内
原文链接:
保证数据引用在数据的边界范围内是程序员一定要负全责的。同理,当程序员使用标准模板容器库,也需要确保索引在容器范围之内。
Ensuring that array references are within the bounds of the array is almost entirely the responsibility of the programmer. Likewise, when using standard template library vectors, the programmer is responsible for ensuring integer indexes are within the bounds of the vector.
不合规代码示例(指针) Noncompliant Code Example (Pointers)
这个不合规代码示例展示了一个函数,insert_in_table()
,包含两个 int
参数,pos
和 value
,会受来自不可信源的数据影响。函数执行了范围检查以确保 pos
不会超出数组的上界,由 tableSize
指定,但是未检查下界。因为 pos
被声明为一个 (signed) int
,这个参数可以设想为一个负数,导致一次超出 table
引用的内存范围的写入。
This noncompliant code example shows a function, insert_in_table()
, that has two int
parameters, pos
and value
, both of which can be influenced by data originating from untrusted sources. The function performs a range check to ensure that pos
does not exceed the upper bound of the array, specified by tableSize
, but fails to check the lower bound. Because pos
is declared as a (signed) int
, this parameter can assume a negative value, resulting in a write outside the bounds of the memory referenced by table
.
1 |
|
合规的方案 (size_t
) Compliant Solution (size_t
)
这个合规的方案中,参数 pos
被声明为 size_t
,可以避免传入负值变量。
In this compliant solution, the parameter pos
is declared as size_t
, which prevents the passing of negative arguments.
1 |
|
合规的方案 (Non-Type Templates) Compliant Solution (Non-Type Templates)
无类型模板可以被用来定义接收一个数组类型的函数,数组边界可以编译器推导。这个合规的方案与先前需要在调用 insert_in_table
时额外提供一个已知边界的边界检查方案,在功能上等价的。
Non-type templates can be used to define functions accepting an array type where the array bounds are deduced at compile time. This compliant solution is functionally equivalent to the previous bounds-checking one except that it additionally supports calling insert_in_table()
with an array of known bounds.
1 |
|
不合规代码示例 (std::vector
) Noncompliant Code Example (std::vector
)
在这个不合规的代码示例中,std::vector
被用来替换指针和尺寸。这个函数执行一次范围检查确保 pos
不会超出容器的上边界。因为 pos
被声明为一个 (signed) long long
,这个参数可以是负数。在把 std::vector::size_type
以 unsigned int
来实现的系统中 (例如 Microsoft Visual Studio2013),对于比较表达式,一般的算数转换会被用来将无符号值转换为有符号值。如果 pos
是一个负值, 这次比较将不会失败,当负值在索引操作中被解释为一个大的无符号值,将导致一次 std::vector
对象的越界写入。
In this noncompliant code example, a std::vector
is used in place of a pointer and size pair. The function performs a range check to ensure that pos
does not exceed the upper bound of the container. Because pos
is declared as a (signed) long long
, this parameter can assume a negative value. On systems where std::vector::size_type
is ultimately implemented as an unsigned int
(such as with Microsoft Visual Studio2013), the usual arithmetic conversions applied for the comparison expression will convert the unsigned value to a signed value. If pos
has a negative value, this comparison will not fail, resulting in a write outside the bounds of the std::vector
object when the negative value is interpreted as a large unsigned value in the indexing operator.
1 |
|
合规方案 (std::vector
, size_t
) Compliant Solution (std::vector
, size_t
)
在这个合规的方案中,参数 pos
被声明为 size_t
,确保了当给定一个大的正数 (从一个负数变量转换而来), 比较表达式执行失败。
In this compliant solution, the parameter pos
is declared as size_t
, which ensures that the comparison expression will fail when a large, positive value (converted from a negative argument) is given.
1 |
|
合规的方案 (std::vector::at()
) Compliant Solution (std::vector::at()
)
这个合规的方案中,通过 at()
方法来访问容器。这个方案提供了边界检查,如果 pos
不是一个有效的索引值时,抛出一个 std::out_of_range
异常。insert_in_table()
被定义为一个 noexcept(false)
函数,符合 ERR55-CPP. Honor exception specifications 。
In this compliant solution, access to the vector is accomplished with the at()
method. This method provides bounds checking, throwing a std::out_of_range
exception if pos
is not a valid index value. The insert_in_table()
function is declared with noexcept(false)
in compliance with ERR55-CPP. Honor exception specifications.
1 |
|
不合规代码示例 (Iterrators) Noncompliant Code Example (Iterators)
在这个不合规的代码示例中,函数 f_imp()
给定了 (正确的) 容器尾迭代器 e
,b
是同个容器的迭代器。然而,b
不在该容器的有效范围内也是有可能的。举个例子,如果容器是空的,b
将和 e
相等,导致不正确的引用。
In this noncompliant code example, the f_imp()
function is given the (correct) ending iterator e
for a container, and b
is an iterator from the same container. However, it is possible that b
is not within the valid range of its container. For instance, if the container were empty, b
would equal e
and be improperly dereferenced.
1 |
|
合规方案 Compliant Solution
这个合规方案在试图解引用 b
前对迭代器有效性做了测试。
This compliant solution tests for iterator validity before attempting to dereference b.
1 |
|
Risk Assessment
Using an invalid array or container index can result in an arbitrary memory overwrite or abnormal program termination.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CTR50-CPP | High | Likely | High | P9 | L2 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
CodeSonar | 5.3p0 | **LANG.MEM.BO LANG.MEM.BU LANG.MEM.TO LANG.MEM.TU **LANG.MEM.TBA **LANG.STRUCT.PBB ****LANG.STRUCT.PPE** | Buffer overrun Buffer underrun Type overrun Type underrun Tainted buffer access Pointer before beginning of object Pointer past end of object |
Klocwork | 2018 | ABV.ANY_SIZE_ARRAY ABV.GENERAL ABV.STACK ABV.TAINTED SV.TAINTED.ALLOC_SIZE SV.TAINTED.CALL.INDEX_ACCESS SV.TAINTED.CALL.LOOP_BOUND SV.TAINTED.INDEX_ACCESS | |
LDRA tool suite | 9.7.1 | 45 D, 47 S, 476 S, 489 S, 64 X, 66 X, 68 X, 69 X, 70 X, 71 X, 79 X** ** | Partially implemented |
Parasoft C/C++test | 10.4.2 | CERT_CPP-CTR50-a | Guarantee that container indices are within the valid range |
Polyspace Bug Finder | R2020a | CERT C++: CTR50-CPP | Checks for:Array access out of boundsArray access with tainted indexPointer dereference with tainted offsetRule partially covered. |
PRQA QA-C++ | 4.4 | 2891, 3139, 3140 | |
PVS-Studio | 7.07 | V781 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C Coding Standard | ARR30-C. Do not form or use out-of-bounds pointers or array subscripts |
---|---|
MITRE CWE | CWE 119, Failure to Constrain Operations within the Bounds of a Memory Buffer CWE 129, Improper Validation of Array Index |
Bibliography
[ISO/IEC 14882-2014] | Clause 23, “Containers Library” Subclause 24.2.1, “In General” |
---|---|
[ISO/IEC TR 24772-2013] | Boundary Beginning Violation [XYX] Wrap-Around Error [XYY] Unchecked Array Indexing [XYZ] |
[Viega 2005] | Section 5.2.13, “Unchecked Array Indexing” |
本文标题:CTR50-CPP. 保证容器索引和迭代器在有效范围内
文章作者:xwnb
发布时间:2020-06-25
最后更新:2023-04-17
原始链接:https://xwnb.github.io/posts/2396132143/
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!并保留本声明。感谢您的阅读和支持!
分享