Skip to content

Commit fec7e5d

Browse files
committed
work
1 parent 8cfed06 commit fec7e5d

File tree

2 files changed

+14
-72
lines changed

2 files changed

+14
-72
lines changed

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

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,10 @@
1414

1515
import cpp
1616
import codingstandards.cpp.cert
17-
import codingstandards.cpp.Concurrency
18-
import semmle.code.cpp.dataflow.DataFlow
19-
import semmle.code.cpp.dataflow.TaintTracking
17+
import codingstandards.cpp.rules.donotallowamutextogooutofscopewhilelocked.DoNotAllowAMutexToGoOutOfScopeWhileLocked
2018

21-
/*
22-
* This query finds potential misuse of mutexes passed to threads by considering
23-
* cases where the underlying mutex is a local variable; such a variable would
24-
* go out of scope at the end of the calling function and thus would potentially
25-
* create issues for the thread depending on the mutex. This query is primarily
26-
* targeted at C usages since in the case of CPP, many more cases can be covered
27-
* via tracking of destructors. The main difference is that this query doesn't
28-
* expect an explicitly deleted call to be made.
29-
*
30-
* In order to safely destroy a dependent mutex, it is necessary both to not delete
31-
* it, but also if deletes do happen, one must wait for a thread to exit prior to
32-
* deleting it. We broadly model this by using standard language support for thread
33-
* synchronization.
34-
*/
35-
from ThreadDependentMutex dm, LocalVariable lv
36-
where
37-
not isExcluded(dm.asExpr(), ConcurrencyPackage::doNotDestroyAMutexWhileItIsLockedQuery()) and
38-
not isExcluded(lv, ConcurrencyPackage::doNotDestroyAMutexWhileItIsLockedQuery()) and
39-
not lv.isStatic() and
40-
TaintTracking::localTaint(dm.getAUsage(), DataFlow::exprNode(lv.getAnAssignedValue()))
41-
// ensure that each dependent thread is followed by some sort of joining
42-
// behavior.
43-
and exists(DataFlow::Node n | n = dm.getADependentThreadCreationExpr() | forall(ThreadWait tw |
44-
not (tw = n.asExpr().getASuccessor*())
45-
))
46-
47-
select dm, "Mutex used by thread potentially destroyed while in use."
19+
class DoNotAllowAMutexToGoOutOfScopeWhileLockedQuery extends DoNotAllowAMutexToGoOutOfScopeWhileLockedSharedQuery {
20+
DoNotAllowAMutexToGoOutOfScopeWhileLockedQuery() {
21+
this = ConcurrencyPackage::doNotAllowAMutexToGoOutOfScopeWhileLockedQuery()
22+
}
23+
}

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

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,47 +10,13 @@
1010
* concurrency
1111
* external/cert/obligation/rule
1212
*/
13+
1314
import cpp
1415
import codingstandards.cpp.cert
15-
import codingstandards.cpp.Concurrency
16-
import semmle.code.cpp.dataflow.DataFlow
17-
import semmle.code.cpp.dataflow.TaintTracking
18-
/*
19-
* This query finds potential misuse of mutexes passed to threads by considering
20-
* cases where the underlying mutex may be destroyed. The scope of this query is
21-
* that it performs this analysis both locally within the function but can also
22-
* look through to the called thread to identify mutexes it may not own.
23-
* query is that it considers this behavior locally within the procedure.
24-
*
25-
* In order to safely destroy a dependent mutex, it is necessary both to not delete
26-
* it, but also if deletes do happen, one must wait for a thread to exit prior to
27-
* deleting it. We broadly model this by using standard language support for thread
28-
* synchronization.
29-
*/
30-
from ThreadDependentMutex dm, MutexDestroyer md
31-
where
32-
not isExcluded(dm.asExpr(), ConcurrencyPackage::doNotDestroyAMutexWhileItIsLockedQuery()) and
33-
not isExcluded(md, ConcurrencyPackage::doNotDestroyAMutexWhileItIsLockedQuery()) and
34-
// find all instances where a usage of a dependent mutex flows into a
35-
// expression that will destroy it.
36-
TaintTracking::localTaint(dm.getAUsage(), DataFlow::exprNode(md.getMutexExpr()))
37-
and
38-
(
39-
// firstly, we assume it is never safe to destroy a global mutex, but it is
40-
// difficult to make assumptions about the intended control flow. Note that
41-
// this means the point at where the mutex is defined -- not where the variable
42-
// that contains it is scoped -- a `ThreadDependentMutex` is bound to the
43-
// function that creates an initialized mutex. For example, in `C`
44-
// `mtx_init` is called to initialize the mutex and in C++, the constructor
45-
// of std::mutex is called.
46-
not exists(dm.asExpr().getEnclosingFunction()) or
47-
// secondly, we assume it is never safe to destroy a mutex created by
48-
// another function scope -- which includes trying to destroy a mutex that
49-
// was passed into a function.
50-
not md.getMutexExpr().getEnclosingFunction() = dm.asExpr().getEnclosingFunction() or
51-
// this leaves only destructions of mutexes locally near the thread that may
52-
// consume them. We allow this only if there has been some effort to
53-
// synchronize the threads prior to destroying the mutex.
54-
not exists(ThreadWait tw | tw = md.getAPredecessor*())
55-
)
56-
select dm, "Mutex used by thread potentially $@ while in use.", md, "destroyed"
16+
import codingstandards.cpp.rules.donotdestroyamutexwhileitislocked.DoNotDestroyAMutexWhileItIsLocked
17+
18+
class DoNotDestroyAMutexWhileItIsLockedQuery extends DoNotDestroyAMutexWhileItIsLockedSharedQuery {
19+
DoNotDestroyAMutexWhileItIsLockedQuery() {
20+
this = ConcurrencyPackage::doNotDestroyAMutexWhileItIsLockedQuery()
21+
}
22+
}

0 commit comments

Comments
 (0)