@@ -501,13 +501,42 @@ class C11MutexSource extends MutexSource, FunctionCall {
501
501
502
502
/**
503
503
* 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.
505
510
*/
506
- class ThreadDependentMutex extends DataFlow:: Node {
511
+ abstract class ThreadDependentMutex extends DataFlow:: Node {
512
+ DataFlow:: Node sink ;
513
+
514
+ }
515
+ class FlowBasedThreadDependentMutex extends ThreadDependentMutex {
507
516
DataFlow:: Node sink ;
508
517
509
518
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
+ )
511
540
}
512
541
513
542
DataFlow:: Node getASource ( ) {
@@ -524,10 +553,23 @@ class ThreadDependentMutex extends DataFlow::Node {
524
553
* dependent mutex.
525
554
*/
526
555
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.
527
562
exists ( FunctionCall fc , Function f , int n |
563
+ // Get the argument to which the mutex flowed.
528
564
fc .getArgument ( n ) = sink .asExpr ( ) and
565
+ // Get the thread function we are calling.
529
566
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 ( ) ) )
531
573
)
532
574
}
533
575
@@ -543,11 +585,17 @@ class ThreadDependentMutex extends DataFlow::Node {
543
585
}
544
586
545
587
/**
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.
547
590
*/
548
591
DataFlow:: Node getAUsage ( ) { TaintTracking:: localTaint ( getASource ( ) , result ) }
549
592
}
550
593
594
+ class AccessBasedThreadDependentMutex extends ThreadDependentMutex {
595
+
596
+ }
597
+
598
+
551
599
class ThreadDependentMutexTaintTrackingConfiguration extends TaintTracking:: Configuration {
552
600
ThreadDependentMutexTaintTrackingConfiguration ( ) {
553
601
this = "ThreadDependentMutexTaintTrackingConfiguration"
0 commit comments