Skip to content

Commit 98667ec

Browse files
committed
work
1 parent 7add99f commit 98667ec

File tree

8 files changed

+241
-0
lines changed

8 files changed

+241
-0
lines changed

.vscode/tasks.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@
199199
"Concurrency1",
200200
"Concurrency2",
201201
"Concurrency3",
202+
"Concurrency4",
202203
"Conditionals",
203204
"Const",
204205
"DeadCode",
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# CON34-C: Declare objects shared between threads with appropriate storage durations
2+
3+
This query implements the CERT-C rule CON34-C:
4+
5+
> Declare objects shared between threads with appropriate storage durations
6+
7+
8+
## CERT
9+
10+
** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` **
11+
12+
## Implementation notes
13+
14+
None
15+
16+
## References
17+
18+
* CERT-C: [CON34-C: Declare objects shared between threads with appropriate storage durations](https://wiki.sei.cmu.edu/confluence/display/c)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* @id c/cert/appropriate-thread-object-storage-durations
3+
* @name CON34-C: Declare objects shared between threads with appropriate storage durations
4+
* @description Accessing thread-local variables with automatic storage durations can lead to
5+
* unpredictable program behavior.
6+
* @kind problem
7+
* @precision high
8+
* @problem.severity error
9+
* @tags external/cert/id/con34-c
10+
* correctness
11+
* concurrency
12+
* external/cert/obligation/rule
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.cert
17+
import codingstandards.cpp.Concurrency
18+
import semmle.code.cpp.dataflow.TaintTracking
19+
20+
21+
/// anything from tss_get is ok. the tss get must obtain the value from the
22+
// context that called tss_set NOT in the thread.
23+
/// anything that was static is ok
24+
/// anything dynamically allocated is ok.
25+
26+
// THREAD LOCAL IS NOT OK -- EG STACK VARIBLES ARE NEVER OK
27+
28+
// we can make this really simple -- just look for thread create functions
29+
// wherein you pass in a variable created on the stack that is a) not static or
30+
// b) not created via malloc and c) not obtained from tss_get.
31+
// we should do something more to determine if tss_get is wrongly called from a
32+
// thread context without a matching tss_get as another query. That should be an
33+
// audit. tss get without set.
34+
// tss_get in the parent thread should maybe be followed by a thread_join
35+
// function
36+
//
37+
//
38+
39+
// IN THE PARENT -- a call to tss_set MUST be followed by a thread_join.
40+
// Without this, it is possible the context isn't valid anymore.
41+
42+
// It's important to note -- tss_get set DOES NOT require a call to delete
43+
// to require the wait. It just requires the wait if it is used at all.
44+
45+
class MallocFunctionCall extends FunctionCall {
46+
MallocFunctionCall(){
47+
getTarget().getName() = "malloc"
48+
}
49+
}
50+
51+
from MallocFunctionCall fc, StackVariable sv, Expr e
52+
where not isExcluded(fc)
53+
and TaintTracking::localTaint(DataFlow::exprNode(fc), DataFlow::exprNode(e))
54+
select fc, e
55+
56+
57+
// from C11ThreadCreateCall tcc, StackVariable sv, Expr arg
58+
// where
59+
// not isExcluded(tcc, Concurrency4Package::appropriateThreadObjectStorageDurationsQuery()) and
60+
// tcc.getArgument(2) = arg and
61+
// // a stack variable that is given as an argument to a thread
62+
// TaintTracking::localTaint(DataFlow::exprNode(sv.getAnAccess()), DataFlow::exprNode(arg))
63+
// // that isn't one of the allowed usage patterns
64+
// TaintTracking::localTaint(DataFlow::exprNode(sv.getAnAccess()), DataFlow::exprNode(arg))
65+
// select tcc, "$@ not declared with appropriate storage duration", arg, "Shared object"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
No expected results have yet been specified
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/CON34-C/AppropriateThreadObjectStorageDurations.ql
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtype Concurrency4Query =
7+
TCleanUpThreadSpecificStorageQuery() or
8+
TAppropriateThreadObjectStorageDurationsQuery() or
9+
TThreadWasPreviouslyJoinedOrDetachedQuery() or
10+
TDoNotReferToAnAtomicVariableTwiceInExpressionQuery()
11+
12+
predicate isConcurrency4QueryMetadata(Query query, string queryId, string ruleId) {
13+
query =
14+
// `Query` instance for the `cleanUpThreadSpecificStorage` query
15+
Concurrency4Package::cleanUpThreadSpecificStorageQuery() and
16+
queryId =
17+
// `@id` for the `cleanUpThreadSpecificStorage` query
18+
"c/cert/clean-up-thread-specific-storage" and
19+
ruleId = "CON30-C"
20+
or
21+
query =
22+
// `Query` instance for the `appropriateThreadObjectStorageDurations` query
23+
Concurrency4Package::appropriateThreadObjectStorageDurationsQuery() and
24+
queryId =
25+
// `@id` for the `appropriateThreadObjectStorageDurations` query
26+
"c/cert/appropriate-thread-object-storage-durations" and
27+
ruleId = "CON34-C"
28+
or
29+
query =
30+
// `Query` instance for the `threadWasPreviouslyJoinedOrDetached` query
31+
Concurrency4Package::threadWasPreviouslyJoinedOrDetachedQuery() and
32+
queryId =
33+
// `@id` for the `threadWasPreviouslyJoinedOrDetached` query
34+
"c/cert/thread-was-previously-joined-or-detached" and
35+
ruleId = "CON39-C"
36+
or
37+
query =
38+
// `Query` instance for the `doNotReferToAnAtomicVariableTwiceInExpression` query
39+
Concurrency4Package::doNotReferToAnAtomicVariableTwiceInExpressionQuery() and
40+
queryId =
41+
// `@id` for the `doNotReferToAnAtomicVariableTwiceInExpression` query
42+
"c/cert/do-not-refer-to-an-atomic-variable-twice-in-expression" and
43+
ruleId = "CON40-C"
44+
}
45+
46+
module Concurrency4Package {
47+
Query cleanUpThreadSpecificStorageQuery() {
48+
//autogenerate `Query` type
49+
result =
50+
// `Query` type for `cleanUpThreadSpecificStorage` query
51+
TQueryC(TConcurrency4PackageQuery(TCleanUpThreadSpecificStorageQuery()))
52+
}
53+
54+
Query appropriateThreadObjectStorageDurationsQuery() {
55+
//autogenerate `Query` type
56+
result =
57+
// `Query` type for `appropriateThreadObjectStorageDurations` query
58+
TQueryC(TConcurrency4PackageQuery(TAppropriateThreadObjectStorageDurationsQuery()))
59+
}
60+
61+
Query threadWasPreviouslyJoinedOrDetachedQuery() {
62+
//autogenerate `Query` type
63+
result =
64+
// `Query` type for `threadWasPreviouslyJoinedOrDetached` query
65+
TQueryC(TConcurrency4PackageQuery(TThreadWasPreviouslyJoinedOrDetachedQuery()))
66+
}
67+
68+
Query doNotReferToAnAtomicVariableTwiceInExpressionQuery() {
69+
//autogenerate `Query` type
70+
result =
71+
// `Query` type for `doNotReferToAnAtomicVariableTwiceInExpression` query
72+
TQueryC(TConcurrency4PackageQuery(TDoNotReferToAnAtomicVariableTwiceInExpressionQuery()))
73+
}
74+
}

cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Banned
66
import Concurrency1
77
import Concurrency2
88
import Concurrency3
9+
import Concurrency4
910
import Contracts1
1011
import Declarations1
1112
import IO1
@@ -31,6 +32,7 @@ newtype TCQuery =
3132
TConcurrency1PackageQuery(Concurrency1Query q) or
3233
TConcurrency2PackageQuery(Concurrency2Query q) or
3334
TConcurrency3PackageQuery(Concurrency3Query q) or
35+
TConcurrency4PackageQuery(Concurrency4Query q) or
3436
TContracts1PackageQuery(Contracts1Query q) or
3537
TDeclarations1PackageQuery(Declarations1Query q) or
3638
TIO1PackageQuery(IO1Query q) or
@@ -56,6 +58,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId) {
5658
isConcurrency1QueryMetadata(query, queryId, ruleId) or
5759
isConcurrency2QueryMetadata(query, queryId, ruleId) or
5860
isConcurrency3QueryMetadata(query, queryId, ruleId) or
61+
isConcurrency4QueryMetadata(query, queryId, ruleId) or
5962
isContracts1QueryMetadata(query, queryId, ruleId) or
6063
isDeclarations1QueryMetadata(query, queryId, ruleId) or
6164
isIO1QueryMetadata(query, queryId, ruleId) or

rule_packages/c/Concurrency4.json

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"CERT-C": {
3+
"CON30-C": {
4+
"properties": {
5+
"obligation": "rule"
6+
},
7+
"queries": [
8+
{
9+
"description": "",
10+
"kind": "problem",
11+
"name": "Clean up thread-specific storage",
12+
"precision": "medium",
13+
"severity": "error",
14+
"short_name": "CleanUpThreadSpecificStorage",
15+
"tags": []
16+
}
17+
],
18+
"title": "Clean up thread-specific storage"
19+
},
20+
"CON34-C": {
21+
"properties": {
22+
"obligation": "rule"
23+
},
24+
"queries": [
25+
{
26+
"description": "Accessing thread-local variables with automatic storage durations can lead to unpredictable program behavior.",
27+
"kind": "problem",
28+
"name": "Declare objects shared between threads with appropriate storage durations",
29+
"precision": "high",
30+
"severity": "error",
31+
"short_name": "AppropriateThreadObjectStorageDurations",
32+
"tags": [
33+
"correctness",
34+
"concurrency"
35+
],
36+
"implementation_scope": {
37+
"description": "This query does not consider Windows implementations or OpenMP implementations. This query is primarily about excluding cases wherein the storage duration of a variable is appropriate. As such, this query is not concerned if the appropriate synchronization mechanisms are used, such as sequencing calls to `thrd_join` and `free`. An audit query is supplied to handle those cases."
38+
}
39+
}
40+
],
41+
"title": "Declare objects shared between threads with appropriate storage durations"
42+
},
43+
"CON39-C": {
44+
"properties": {
45+
"obligation": "rule"
46+
},
47+
"queries": [
48+
{
49+
"description": "",
50+
"kind": "problem",
51+
"name": "Do not join or detach a thread that was previously joined or detached",
52+
"precision": "high",
53+
"severity": "error",
54+
"short_name": "ThreadWasPreviouslyJoinedOrDetached",
55+
"tags": []
56+
}
57+
],
58+
"title": "Do not join or detach a thread that was previously joined or detached"
59+
},
60+
"CON40-C": {
61+
"properties": {
62+
"obligation": "rule"
63+
},
64+
"queries": [
65+
{
66+
"description": "",
67+
"kind": "problem",
68+
"name": "Do not refer to an atomic variable twice in an expression",
69+
"precision": "very-high",
70+
"severity": "error",
71+
"short_name": "DoNotReferToAnAtomicVariableTwiceInExpression",
72+
"tags": []
73+
}
74+
],
75+
"title": "Do not refer to an atomic variable twice in an expression"
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)