|
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