CON56-CPP. 不要对当前线程已经拥有的非递归互斥体进行假想锁定
原文链接:
CON55-CPP. Preserve thread safety and liveness when using condition variables
C++标准库提供递归和非递归互斥量类型用于保护临界区。递归互斥体类(std::recursive_mutex 和 std::recursive_timed_mutex)与非递归互斥量(std::mutex
、std::timed_mutex
和 std::shared_timed_mutex
)的不同之处在于,递归互斥量可以被当前拥有互斥量线程递归地锁定。所有互斥量类型都具有对互斥量进行尝试锁定的能力,通过诸如 try_lock()
、try_lock_for()
、try_lock_until()
、try_lock_shared_for()
和 try_lock_shared_until()
等函数实现。这些尝试锁定函数试图为当前线程获取互斥量的所有权,但在无法获得所有权的情况下不会阻塞。相反,它们会返回一个布尔值,表明是否已经获得了互斥量的所有权。
C++标准中的[thead.mutex.requirements.mutex] 第14和15段(ISO/IEC 14882-2014)规定如下:
表达式
m.try_lock()
应该是形式完备的,并具有以下语义:
要求:如果m
是类型std::mutex
、std::timed_mutex
或std::shared_timed_mutex
,则调用线程不拥有互斥体。
此外,[thread.timedmutex.class]第3段部分规定如下:
如果一个拥有
timed_mutex
对象的线程调用该对象的lock()
、try_lock()
、try_lock_for()
或try_lock_until()
,程序的行为未定义。
最后,[thread.sharedtimedmutex.class]第3段部分规定如下:
如果一个线程试图递归地获取
shared_timed_mutex
的任何所有权,则程序的行为未定义。
因此,试图对已经被当前线程拥有所有权的非递归互斥量对象进行尝试锁定是未定义行为。不要对那些已经被线程拥有所有权的非递归互斥量对象上调用 try_lock()
、try_lock_for()
、try_lock_until()
、try_lock_shared_for()
或 try_lock_shared_until()
。
不合规代码示例
在下面这个不合规代码示例代码中,互斥量 m
被线程的初始入口点锁定,然后在同一线程的 do_work()
函数中再尝试尝试锁定,导致未定义行为,因为它不是一个递归互斥量 。这通常可能导致死锁。
1 |
|
合规解决方案
这个合规方案从线程的初始入口点中删除了锁定,允许对互斥体进行尝试锁定,但不允许递归。
1 |
|
Risk Assessment
Speculatively locking a non-recursive mutex in a recursive manner is undefined behavior that can lead to deadlock.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CON56-CPP | Low | Unlikely | High | P1 | L3 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
CodeSonar | 7.3p0 | CONCURRENCY.TL | Try-lock that will never succeed |
Helix QAC | 2023.1 | C++4986, C++4987 | |
Parasoft C/C++test | 2022.2 | CERT_CPP-CON56-a | Avoid double locking |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
MITRE CWE | CWE-667, Improper Locking |
---|---|
Bibliography
[ISO/IEC 14882-2014] | Subclause 30.4.1, “Mutex Requirements” |
---|---|
本文标题:CON56-CPP. 不要对当前线程已经拥有的非递归互斥体进行假想锁定
文章作者:xwnb
发布时间:2023-04-01
最后更新:2023-04-17
原始链接:https://xwnb.github.io/posts/176443133/
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!并保留本声明。感谢您的阅读和支持!
分享