|
10 | 10 | * concurrency
|
11 | 11 | * external/cert/obligation/rule
|
12 | 12 | */
|
| 13 | + |
13 | 14 | import cpp
|
14 | 15 | 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