Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8458865

Browse filesBrowse files
authored
Merge branch 'main' into kraiouchkine-dev
2 parents 44cdbeb + cc527b1 commit 8458865
Copy full SHA for 8458865

File tree

Expand file treeCollapse file tree

370 files changed

+6820
-766
lines changed
Filter options

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree

370 files changed

+6820
-766
lines changed

‎.vscode/tasks.json

Copy file name to clipboardExpand all lines: .vscode/tasks.json
+25-3Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,28 @@
9696
},
9797
"problemMatcher": []
9898
},
99+
{
100+
"label": "📖 Standards Automation: Generate Help Files for CERT rules",
101+
"type": "shell",
102+
"windows": {
103+
"command": ".${pathSeparator}scripts${pathSeparator}.venv${pathSeparator}Scripts${pathSeparator}python.exe scripts${pathSeparator}help${pathSeparator}cert-help-extraction.py ${input:rule}"
104+
},
105+
"linux": {
106+
"command": ".${pathSeparator}scripts${pathSeparator}.venv${pathSeparator}bin${pathSeparator}python3 scripts${pathSeparator}help${pathSeparator}cert-help-extraction.py ${input:rule}"
107+
},
108+
"osx": {
109+
"command": ".${pathSeparator}scripts${pathSeparator}.venv${pathSeparator}bin${pathSeparator}python3 scripts${pathSeparator}help${pathSeparator}cert-help-extraction.py ${input:rule}"
110+
},
111+
"presentation": {
112+
"reveal": "always",
113+
"panel": "new",
114+
"focus": true
115+
},
116+
"runOptions": {
117+
"reevaluateOnRerun": false
118+
},
119+
"problemMatcher": []
120+
},
99121
{
100122
"label": "🧪 Standards Automation: Build Case Test DB",
101123
"type": "shell",
@@ -163,14 +185,13 @@
163185
"type": "pickString",
164186
"options": [
165187
"Allocations",
166-
"Banned",
167188
"BannedFunctions",
189+
"BannedLibraries",
168190
"BannedSyntax",
169191
"BannedTypes",
170192
"Classes",
171-
"Classes",
172-
"Classes",
173193
"Comments",
194+
"Contracts1",
174195
"Concurrency",
175196
"Concurrency",
176197
"Concurrency1",
@@ -180,6 +201,7 @@
180201
"Const",
181202
"DeadCode",
182203
"Declarations",
204+
"Declarations1",
183205
"Exceptions1",
184206
"Exceptions2",
185207
"Expressions",
+172Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# CON31-C: Do not destroy a mutex while it is locked
2+
3+
This query implements the CERT-C rule CON31-C:
4+
5+
> Do not destroy a mutex while it is locked
6+
7+
8+
## Description
9+
10+
Mutexes are used to protect shared data structures being concurrently accessed. If a mutex is destroyed while a thread is blocked waiting for that mutex, [critical sections](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-criticalsections) and shared data are no longer protected.
11+
12+
The C Standard, 7.26.4.1, paragraph 2 \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)\], states
13+
14+
> The `mtx_destroy` function releases any resources used by the mutex pointed to by `mtx`. No threads can be blocked waiting for the mutex pointed to by `mtx`.
15+
16+
17+
This statement implies that destroying a mutex while a thread is waiting on it is [undefined behavior](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior).
18+
19+
## Noncompliant Code Example
20+
21+
This noncompliant code example creates several threads that each invoke the `do_work()` function, passing a unique number as an ID. The `do_work()` function initializes the `lock` mutex if the argument is 0 and destroys the mutex if the argument is `max_threads - 1`. In all other cases, the `do_work()` function provides normal processing. Each thread, except the final cleanup thread, increments the atomic `completed` variable when it is finished.
22+
23+
Unfortunately, this code contains several race conditions, allowing the mutex to be destroyed before it is unlocked. Additionally, there is no guarantee that `lock` will be initialized before it is passed to `mtx_lock()`. Each of these behaviors is [undefined](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior).
24+
25+
```cpp
26+
#include <stdatomic.h>
27+
#include <stddef.h>
28+
#include <threads.h>
29+
30+
mtx_t lock;
31+
/* Atomic so multiple threads can modify safely */
32+
atomic_int completed = ATOMIC_VAR_INIT(0);
33+
enum { max_threads = 5 };
34+
35+
int do_work(void *arg) {
36+
int *i = (int *)arg;
37+
38+
if (*i == 0) { /* Creation thread */
39+
if (thrd_success != mtx_init(&lock, mtx_plain)) {
40+
/* Handle error */
41+
}
42+
atomic_store(&completed, 1);
43+
} else if (*i < max_threads - 1) { /* Worker thread */
44+
if (thrd_success != mtx_lock(&lock)) {
45+
/* Handle error */
46+
}
47+
/* Access data protected by the lock */
48+
atomic_fetch_add(&completed, 1);
49+
if (thrd_success != mtx_unlock(&lock)) {
50+
/* Handle error */
51+
}
52+
} else { /* Destruction thread */
53+
mtx_destroy(&lock);
54+
}
55+
return 0;
56+
}
57+
58+
int main(void) {
59+
thrd_t threads[max_threads];
60+
61+
for (size_t i = 0; i < max_threads; i++) {
62+
if (thrd_success != thrd_create(&threads[i], do_work, &i)) {
63+
/* Handle error */
64+
}
65+
}
66+
for (size_t i = 0; i < max_threads; i++) {
67+
if (thrd_success != thrd_join(threads[i], 0)) {
68+
/* Handle error */
69+
}
70+
}
71+
return 0;
72+
}
73+
74+
```
75+
76+
## Compliant Solution
77+
78+
This compliant solution eliminates the race conditions by initializing the mutex in `main()` before creating the threads and by destroying the mutex in `main()` after joining the threads:
79+
80+
```cpp
81+
#include <stdatomic.h>
82+
#include <stddef.h>
83+
#include <threads.h>
84+
85+
mtx_t lock;
86+
/* Atomic so multiple threads can increment safely */
87+
atomic_int completed = ATOMIC_VAR_INIT(0);
88+
enum { max_threads = 5 };
89+
90+
int do_work(void *dummy) {
91+
if (thrd_success != mtx_lock(&lock)) {
92+
/* Handle error */
93+
}
94+
/* Access data protected by the lock */
95+
atomic_fetch_add(&completed, 1);
96+
if (thrd_success != mtx_unlock(&lock)) {
97+
/* Handle error */
98+
}
99+
100+
return 0;
101+
}
102+
103+
int main(void) {
104+
thrd_t threads[max_threads];
105+
106+
if (thrd_success != mtx_init(&lock, mtx_plain)) {
107+
/* Handle error */
108+
}
109+
for (size_t i = 0; i < max_threads; i++) {
110+
if (thrd_success != thrd_create(&threads[i], do_work, NULL)) {
111+
/* Handle error */
112+
}
113+
}
114+
for (size_t i = 0; i < max_threads; i++) {
115+
if (thrd_success != thrd_join(threads[i], 0)) {
116+
/* Handle error */
117+
}
118+
}
119+
120+
mtx_destroy(&lock);
121+
return 0;
122+
}
123+
124+
```
125+
126+
## Risk Assessment
127+
128+
Destroying a mutex while it is locked may result in invalid control flow and data corruption.
129+
130+
<table> <tbody> <tr> <th> Rule </th> <th> Severity </th> <th> Likelihood </th> <th> Remediation Cost </th> <th> Priority </th> <th> Level </th> </tr> <tr> <td> CON31-C </td> <td> Medium </td> <td> Probable </td> <td> High </td> <td> <strong>P4</strong> </td> <td> <strong>L3</strong> </td> </tr> </tbody> </table>
131+
132+
133+
## Automated Detection
134+
135+
<table> <tbody> <tr> <th> Tool </th> <th> Version </th> <th> Checker </th> <th> Description </th> </tr> <tr> <td> <a> Astrée </a> </td> <td> 22.04 </td> <td> </td> <td> Supported, but no explicit checker </td> </tr> <tr> <td> <a> CodeSonar </a> </td> <td> 7.0p0 </td> <td> <strong>CONCURRENCY.LOCALARG</strong> </td> <td> Local Variable Passed to Thread </td> </tr> <tr> <td> <a> Helix QAC </a> </td> <td> 2022.2 </td> <td> <strong>C4961, C4962</strong> </td> <td> </td> </tr> <tr> <td> <a> PRQA QA-C </a> </td> <td> 9.7 </td> <td> <strong>4961, 4962 </strong> </td> <td> </td> </tr> <tr> <td> <a> Parasoft C/C++test </a> </td> <td> 2022.1 </td> <td> <strong>CERT_C-CON31-a</strong> <strong>CERT_C-CON31-b</strong> <strong>CERT_C-CON31-c</strong> </td> <td> Do not destroy another thread's mutex Do not use resources that have been freed Do not free resources using invalid pointers </td> </tr> <tr> <td> <a> Polyspace Bug Finder </a> </td> <td> R2022a </td> <td> <a> CERT C: Rule CON31-C </a> </td> <td> Checks for destruction of locked mutex (rule fully covered) </td> </tr> </tbody> </table>
136+
137+
138+
## Related Vulnerabilities
139+
140+
Search for [vulnerabilities](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-vulnerability) resulting from the violation of this rule on the [CERT website](https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+CON31-C).
141+
142+
## Related Guidelines
143+
144+
[Key here](https://wiki.sei.cmu.edu/confluence/display/c/How+this+Coding+Standard+is+Organized#HowthisCodingStandardisOrganized-RelatedGuidelines) (explains table format and definitions)
145+
146+
<table> <tbody> <tr> <th> Taxonomy </th> <th> Taxonomy item </th> <th> Relationship </th> </tr> <tr> <td> <a> CWE 2.11 </a> </td> <td> <a> CWE-667 </a> , Improper Locking </td> <td> 2017-07-10: CERT: Rule subset of CWE </td> </tr> </tbody> </table>
147+
148+
149+
## CERT-CWE Mapping Notes
150+
151+
[Key here](https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152408#HowthisCodingStandardisOrganized-CERT-CWEMappingNotes) for mapping notes
152+
153+
**CWE-667 and CON31-C/POS48-C**
154+
155+
Intersection( CON31-C, POS48-C) = Ø
156+
157+
CWE-667 = Union, CON31-C, POS48-C, list) where list =
158+
159+
* Locking &amp; Unlocking issues besides unlocking another thread’s C mutex or pthread mutex.
160+
161+
## Bibliography
162+
163+
<table> <tbody> <tr> <td> \[ <a> ISO/IEC 9899:2011 </a> \] </td> <td> 7.26.4.1, "The <code>mtx_destroy</code> Function" </td> </tr> </tbody> </table>
164+
165+
166+
## Implementation notes
167+
168+
This implementation does not allow for thread synchronization to be performed in subroutines. All synchronization must be performed within the context of the other thread management functions.
169+
170+
## References
171+
172+
* CERT-C: [CON31-C: Do not destroy a mutex while it is locked](https://wiki.sei.cmu.edu/confluence/display/c)
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @id c/cert/do-not-allow-a-mutex-to-go-out-of-scope-while-locked
3+
* @name CON31-C: Do not destroy a mutex while it is locked
4+
* @description Allowing a mutex to go out of scope while it is locked removes protections around
5+
* shared resources.
6+
* @kind problem
7+
* @precision high
8+
* @problem.severity error
9+
* @tags external/cert/id/con31-c
10+
* correctness
11+
* concurrency
12+
* external/cert/obligation/rule
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.cert
17+
import codingstandards.cpp.rules.donotallowamutextogooutofscopewhilelocked.DoNotAllowAMutexToGoOutOfScopeWhileLocked
18+
19+
class DoNotAllowAMutexToGoOutOfScopeWhileLockedQuery extends DoNotAllowAMutexToGoOutOfScopeWhileLockedSharedQuery {
20+
DoNotAllowAMutexToGoOutOfScopeWhileLockedQuery() {
21+
this = Concurrency3Package::doNotAllowAMutexToGoOutOfScopeWhileLockedQuery()
22+
}
23+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.