Skip to content

Commit 7349926

Browse files
committed
work
1 parent e82f522 commit 7349926

File tree

3 files changed

+116
-25
lines changed

3 files changed

+116
-25
lines changed

cpp/cert/src/rules/CON50-CPP/DoNotDestroyAMutexWhileItIsLocked.ql

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@
1010
* concurrency
1111
* external/cert/obligation/rule
1212
*/
13-
1413
import cpp
1514
import codingstandards.cpp.cert
1615
import codingstandards.cpp.Concurrency
1716
import semmle.code.cpp.dataflow.DataFlow
1817
import semmle.code.cpp.dataflow.TaintTracking
19-
20-
2118
/*
2219
* This query finds potential misuse of mutexes passed to threads by considering
2320
* cases where the underlying mutex may be destroyed. The scope of this query is

cpp/cert/test/rules/CON50-CPP/test.c

Lines changed: 113 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,132 @@
11
#include <stdatomic.h>
22
#include <stddef.h>
33
#include <threads.h>
4-
5-
mtx_t mx;
6-
7-
int t1(void *dummy) {
8-
mtx_lock(&mx);
9-
mtx_unlock(&mx);
4+
5+
/// Note that since this is a C test case, mutexes
6+
/// are not created/valid until `mtx_init` is called.
7+
mtx_t mx1;
8+
mtx_t mx2;
9+
10+
int t1(void *data) {
11+
mtx_lock(&mx1);
12+
mtx_unlock(&mx1);
13+
return 0;
14+
}
15+
16+
int t2(void *data) {
17+
mtx_lock(&mx2);
18+
mtx_unlock(&mx2);
19+
return 0;
20+
}
21+
22+
int t3(void *data) {
23+
mtx_t *mxl = (mtx_t *)data;
24+
mtx_lock(mxl);
25+
mtx_unlock(mxl);
1026
return 0;
1127
}
12-
28+
29+
int t4(void *data) {
30+
mtx_t *mxl = (mtx_t *)data;
31+
mtx_lock(mxl);
32+
mtx_unlock(mxl);
33+
return 0;
34+
}
35+
36+
// case 1 - correctly waiting for a well-behaved thread
1337
int f1() {
1438
thrd_t threads[5];
15-
16-
mtx_init(&mx, mtx_plain);
17-
18-
for (size_t i = 0; i < 5; i++) {
39+
40+
mtx_init(&mx1, mtx_plain); // COMPLIANT
41+
42+
for (size_t i = 0; i < 1; i++) {
1943
thrd_create(&threads[i], t1, NULL);
20-
2144
}
22-
for (size_t i = 0; i < 5; i++) {
45+
for (size_t i = 0; i < 1; i++) {
2346
thrd_join(threads[i], 0);
2447
}
25-
26-
mtx_destroy(&mx);
48+
49+
mtx_destroy(&mx1);
2750
return 0;
2851
}
2952

53+
// case 2 - incorrectly waiting for a well behaved thread.
3054
int f2() {
3155
thrd_t threads[5];
32-
33-
mtx_init(&mx, mtx_plain);
34-
35-
for (size_t i = 0; i < 5; i++) {
36-
thrd_create(&threads[i], t1, NULL);
56+
57+
mtx_init(&mx2, mtx_plain); // NON_COMPLIANT
58+
59+
for (size_t i = 0; i < 1; i++) {
60+
thrd_create(&threads[i], t2, NULL);
61+
}
62+
63+
mtx_destroy(&mx2);
64+
return 0;
65+
}
66+
67+
// case 3 - correctly waiting for a well-behaved thread, with a local mutex.
68+
int f3() {
69+
thrd_t threads[5];
70+
71+
mtx_t mxl;
72+
73+
mtx_init(&mxl, mtx_plain); // COMPLIANT
74+
75+
for (size_t i = 0; i < 1; i++) {
76+
thrd_create(&threads[i], t3, &mxl);
77+
}
78+
79+
for (size_t i = 0; i < 1; i++) {
80+
thrd_join(threads[i], 0);
3781
}
3882

39-
mtx_destroy(&mx);
83+
mtx_destroy(&mxl);
4084
return 0;
41-
}
85+
}
86+
87+
// case 4 - incorrectly waiting for a well behaved thread, with a local mutex.
88+
int f4() {
89+
thrd_t threads[5];
90+
mtx_t mxl;
91+
92+
mtx_init(&mxl, mtx_plain); // NON_COMPLIANT
93+
94+
for (size_t i = 0; i < 1; i++) {
95+
thrd_create(&threads[i], t3, &mxl);
96+
}
97+
98+
mtx_destroy(&mxl);
99+
return 0;
100+
}
101+
102+
// case 5 - incorrectly waiting with a stack local variable.
103+
int f5() {
104+
thrd_t threads[5];
105+
mtx_t mxl;
106+
107+
mtx_init(&mxl, mtx_plain); // NON_COMPLIANT
108+
109+
for (size_t i = 0; i < 1; i++) {
110+
thrd_create(&threads[i], t4, &mxl);
111+
}
112+
113+
return 0;
114+
}
115+
116+
// case 6 - correctly waiting with a stack local variable.
117+
int f6() {
118+
thrd_t threads[5];
119+
mtx_t mxl;
120+
121+
mtx_init(&mxl, mtx_plain); // COMPLIANT
122+
123+
for (size_t i = 0; i < 1; i++) {
124+
thrd_create(&threads[i], t4, &mxl);
125+
}
126+
127+
for (size_t i = 0; i < 1; i++) {
128+
thrd_join(threads[i], 0);
129+
}
130+
131+
return 0;
132+
}

cpp/common/src/codingstandards/cpp/Concurrency.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,10 @@ class LocalMutexDestroyer extends MutexDestroyer {
758758

759759
LocalMutexDestroyer() {
760760
exists(LocalVariable lv |
761+
// static types aren't destroyers
761762
not lv.isStatic() and
763+
// neither are pointers
764+
not lv.getType() instanceof PointerType and
762765
lv.getAnAssignedValue() = assignedValue and
763766
// map the location to the return statements of the
764767
// enclosing function

0 commit comments

Comments
 (0)