@@ -501,13 +501,42 @@ class C11MutexSource extends MutexSource, FunctionCall {
501501
502502/**
503503 * Models a thread dependent mutex. A thread dependent mutex is a mutex
504- * that is used by a thread.
504+ * that is used by a thread. This dependency is established either by directly
505+ * passing in a mutex or by referencing a mutex that is in the local scope. The utility
506+ * of this class is it captures the `DataFlow::Node` source at which the mutex
507+ * came from. For example, if it is passed in from a local function to a thread.
508+ * This functionality is critical, since it allows one to inspect how the thread
509+ * behaves with respect to the owner of a resource.
505510 */
506- class ThreadDependentMutex extends DataFlow:: Node {
511+ abstract class ThreadDependentMutex extends DataFlow:: Node {
512+ DataFlow:: Node sink ;
513+
514+ }
515+ class FlowBasedThreadDependentMutex extends ThreadDependentMutex {
507516 DataFlow:: Node sink ;
508517
509518 ThreadDependentMutex ( ) {
510- exists ( ThreadDependentMutexTaintTrackingConfiguration config | config .hasFlow ( this , sink ) )
519+
520+ // this predicate captures two cases. The first being some sort of dataflow,
521+ // likely through parameter passing.
522+ exists ( ThreadDependentMutexTaintTrackingConfiguration config | config .hasFlow ( this , sink ) ) or
523+
524+ // the second encapsulates usages from outside scopes not directly expressed
525+ // in dataflow.
526+ exists ( MutexSource mutexSrc , ThreadedFunction f , Variable variableSource |
527+ DataFlow:: exprNode ( mutexSrc ) = this and
528+
529+ // find a variable that was assigned the mutex
530+ TaintTracking:: localTaint ( DataFlow:: exprNode ( mutexSrc ) , DataFlow:: exprNode ( variableSource .getAnAssignedValue ( ) ) ) and
531+
532+ // find all subsequent accesses of that variable that are within a
533+ // function and set those to the sink
534+ exists ( VariableAccess va |
535+ va = variableSource .getAnAccess ( ) and
536+ va .getEnclosingFunction ( ) = f
537+ and sink = DataFlow:: exprNode ( va )
538+ )
539+ )
511540 }
512541
513542 DataFlow:: Node getASource ( ) {
@@ -524,10 +553,23 @@ class ThreadDependentMutex extends DataFlow::Node {
524553 * dependent mutex.
525554 */
526555 DataFlow:: Node getAThreadSource ( ) {
556+ // here we line up the actual parameter at the thread creation
557+ // site with the formal parameter in the target thread.
558+ // Note that there are differences between the C and C++ versions
559+ // of the argument ordering in the thread creation function. However,
560+ // since the C version only takes one parameter (as opposed to multiple)
561+ // we can simplify this search by considering only the first argument.
527562 exists ( FunctionCall fc , Function f , int n |
563+ // Get the argument to which the mutex flowed.
528564 fc .getArgument ( n ) = sink .asExpr ( ) and
565+ // Get the thread function we are calling.
529566 f = fc .getArgument ( 0 ) .( FunctionAccess ) .getTarget ( ) and
530- result = DataFlow:: exprNode ( f .getParameter ( n - 1 ) .getAnAccess ( ) )
567+ // in C++, there is an extra argument to the `std::thread` call
568+ // so we must subtract 1 since this is not passed to the thread.
569+ ( result = DataFlow:: exprNode ( f .getParameter ( n - 1 ) .getAnAccess ( ) ) or
570+ // In C, only one argument is allowed. Thus IF the flow predicate holds,
571+ // it will be to the first argument
572+ result = DataFlow:: exprNode ( f .getParameter ( 0 ) .getAnAccess ( ) ) )
531573 )
532574 }
533575
@@ -543,11 +585,17 @@ class ThreadDependentMutex extends DataFlow::Node {
543585 }
544586
545587 /**
546- * Gets a set of usages of this mutex in both the local and thread scope.
588+ * Gets a set of usages of this mutex in both the local and thread scope.
589+ * In the case of scoped usage, this also captures typical accesses of variables.
547590 */
548591 DataFlow:: Node getAUsage ( ) { TaintTracking:: localTaint ( getASource ( ) , result ) }
549592}
550593
594+ class AccessBasedThreadDependentMutex extends ThreadDependentMutex {
595+
596+ }
597+
598+
551599class ThreadDependentMutexTaintTrackingConfiguration extends TaintTracking:: Configuration {
552600 ThreadDependentMutexTaintTrackingConfiguration ( ) {
553601 this = "ThreadDependentMutexTaintTrackingConfiguration"
0 commit comments