Skip to content

Commit 1dead2e

Browse files
committed
work
1 parent 40cbfc7 commit 1dead2e

4 files changed

+76
-44
lines changed

c/cert/src/rules/CON34-C/AppropriateThreadObjectStorageDurations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This query implements the CERT-C rule CON34-C:
1111

1212
## Implementation notes
1313

14-
None
14+
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.
1515

1616
## References
1717

c/cert/src/rules/CON34-C/AppropriateThreadObjectStorageDurations.ql

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,50 +16,31 @@ import cpp
1616
import codingstandards.c.cert
1717
import codingstandards.cpp.Concurrency
1818
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.
19+
import semmle.code.cpp.dataflow.DataFlow
4420

4521
class MallocFunctionCall extends FunctionCall {
46-
MallocFunctionCall(){
47-
getTarget().getName() = "malloc"
48-
}
22+
MallocFunctionCall() { getTarget().getName() = "malloc" }
4923
}
5024

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"
25+
from C11ThreadCreateCall tcc, StackVariable sv, Expr arg, Expr acc
26+
where
27+
not isExcluded(tcc, Concurrency4Package::appropriateThreadObjectStorageDurationsQuery()) and
28+
tcc.getArgument(2) = arg and
29+
sv.getAnAccess() = acc and
30+
// a stack variable that is given as an argument to a thread
31+
TaintTracking::localTaint(DataFlow::exprNode(acc), DataFlow::exprNode(arg)) and
32+
// it's either not static
33+
not sv.isStatic() and
34+
// or isn't one of the allowed usage patterns
35+
not exists(MallocFunctionCall mfc |
36+
sv.getAnAssignedValue() = mfc and acc.getAPredecessor*() = mfc
37+
) and
38+
not exists(TSSGetFunctionCall tsg, TSSSetFunctionCall tss, DataFlow::Node src |
39+
sv.getAnAssignedValue() = tsg and
40+
acc.getAPredecessor*() = tsg and
41+
// there should be dataflow from somewhere (the same somewhere)
42+
// into each of the first arguments
43+
DataFlow::localFlow(src, DataFlow::exprNode(tsg.getArgument(0))) and
44+
DataFlow::localFlow(src, DataFlow::exprNode(tss.getArgument(0)))
45+
)
46+
select tcc, "$@ not declared with appropriate storage duration", arg, "Shared object"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# CON34-C: (Audit) 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+
## CERT
7+
8+
** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` **
9+
10+
## Implementation notes
11+
12+
None
13+
14+
## References
15+
16+
* CERT-C: [CON34-C: Declare objects shared between threads with appropriate storage durations](https://wiki.sei.cmu.edu/confluence/display/c)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @id c/cert/thread-object-storage-durations-not-initialized
3+
* @name CON34-C: (Audit) Declare objects shared between threads with appropriate storage durations
4+
* @description Storage durations not correctly initialized can cause unpredictable program
5+
* behavior.
6+
* @kind problem
7+
* @precision high
8+
* @problem.severity error
9+
* @tags external/cert/id/con34-c
10+
* external/autosar/audit
11+
* correctness
12+
* concurrency
13+
* external/cert/obligation/rule
14+
*/
15+
16+
import cpp
17+
import codingstandards.c.cert
18+
import codingstandards.cpp.Concurrency
19+
import semmle.code.cpp.dataflow.TaintTracking
20+
import semmle.code.cpp.dataflow.DataFlow
21+
22+
from TSSGetFunctionCall tsg, ThreadedFunction tf
23+
where
24+
not isExcluded(tsg, Concurrency4Package::threadObjectStorageDurationsNotInitializedQuery()) and
25+
// from within a threaded function there is a call to tsg
26+
tsg.getEnclosingFunction() = tf and
27+
// however, there does not exist a proper sequencing.
28+
not exists(TSSSetFunctionCall tss, DataFlow::Node src |
29+
// there should be dataflow from somewhere (the same somewhere)
30+
// into each of the first arguments
31+
DataFlow::localFlow(src, DataFlow::exprNode(tsg.getArgument(0))) and
32+
DataFlow::localFlow(src, DataFlow::exprNode(tss.getArgument(0)))
33+
)
34+
select tsg,
35+
"Call to a thread specific storage function from within a threaded context on an object that may not be owned by this thread."

0 commit comments

Comments
 (0)