@@ -54,6 +54,24 @@ signature module InputSig<LocationSig Location, DF::InputSig<Location> Lang> {
5454 none ( )
5555 }
5656
57+ /**
58+ * A base class of calls that are candidates for flow summary modeling.
59+ */
60+ class FlowSummaryCallBase {
61+ string toString ( ) ;
62+ }
63+
64+ /** Gets a call that targets summarized callable `sc`. */
65+ default FlowSummaryCallBase getASourceCall ( SummarizedCallableBase sc ) { none ( ) }
66+
67+ /** Gets the callable corresponding to summarized callable `c`. */
68+ default Lang:: DataFlowCallable getSummarizedCallableAsDataFlowCallable ( SummarizedCallableBase c ) {
69+ none ( )
70+ }
71+
72+ /** Gets the enclosing callable of `call`. */
73+ default Lang:: DataFlowCallable getSourceCallEnclosingCallable ( FlowSummaryCallBase call ) { none ( ) }
74+
5775 /** Gets the parameter position representing a callback itself, if any. */
5876 default Lang:: ArgumentPosition callbackSelfParameterPosition ( ) { none ( ) }
5977
@@ -74,6 +92,9 @@ signature module InputSig<LocationSig Location, DF::InputSig<Location> Lang> {
7492 result = getStandardReturnValueKind ( )
7593 }
7694
95+ /** Gets the parameter position corresponding to a flow-summary return kind `rk`, if any. */
96+ default Lang:: ParameterPosition getFlowSummaryParameterPosition ( Lang:: ReturnKind rk ) { none ( ) }
97+
7798 /** Gets the textual representation of parameter position `pos` used in MaD. */
7899 string encodeParameterPosition ( Lang:: ParameterPosition pos ) ;
79100
@@ -660,6 +681,10 @@ module Make<
660681 s .length ( ) = 1 and
661682 s .head ( ) instanceof TArgumentSummaryComponent
662683 or
684+ // ReturnValue.*
685+ s .length ( ) = 1 and
686+ s .head ( ) instanceof TReturnSummaryComponent
687+ or
663688 // Argument[n].ReturnValue.*
664689 s .length ( ) = 2 and
665690 s .head ( ) instanceof TReturnSummaryComponent and
@@ -1137,6 +1162,13 @@ module Make<
11371162 outputState ( c , s ) and s = SummaryComponentStack:: argument ( _)
11381163 }
11391164
1165+ private predicate relevantFlowSummaryPosition ( SummarizedCallable c , ReturnKind rk ) {
1166+ exists ( SummaryComponentStack input |
1167+ summary ( c , input , _, _, _) and
1168+ input = TSingletonSummaryComponentStack ( TReturnSummaryComponent ( rk ) )
1169+ )
1170+ }
1171+
11401172 pragma [ nomagic]
11411173 private predicate sourceOutputStateEntry (
11421174 SourceElement source , SummaryComponentStack s , string kind , string model
@@ -1272,6 +1304,12 @@ module Make<
12721304 TSummaryParameterNode ( SummarizedCallable c , ParameterPosition pos ) {
12731305 summaryParameterNodeRange ( c , pos )
12741306 } or
1307+ TSummaryReturnArgumentNode ( FlowSummaryCallBase call , ReturnKind rk ) {
1308+ exists ( SummarizedCallable sc |
1309+ call = getASourceCall ( sc ) and
1310+ relevantFlowSummaryPosition ( sc , rk )
1311+ )
1312+ } or
12751313 TSourceOutputNode ( SourceElement source , SummaryNodeState state , string kind , string model ) {
12761314 state .isSourceOutputState ( source , _, kind , model )
12771315 } or
@@ -1321,6 +1359,39 @@ module Make<
13211359 override SinkElement getSinkElement ( ) { none ( ) }
13221360 }
13231361
1362+ private class SummaryReturnArgumentNode extends SummaryNode , TSummaryReturnArgumentNode {
1363+ private FlowSummaryCallBase call ;
1364+ private ReturnKind rk ;
1365+
1366+ SummaryReturnArgumentNode ( ) { this = TSummaryReturnArgumentNode ( call , rk ) }
1367+
1368+ override string toString ( ) { result = "[summary] value written to " + rk + " at " + call }
1369+
1370+ override SummarizedCallable getSummarizedCallable ( ) { none ( ) }
1371+
1372+ override SourceElement getSourceElement ( ) { none ( ) }
1373+
1374+ override SinkElement getSinkElement ( ) { none ( ) }
1375+ }
1376+
1377+ /**
1378+ * Gets the summary node that represents the for `call` returning a value
1379+ * with kind `rk`.
1380+ */
1381+ SummaryNode summaryArgumentNode ( FlowSummaryCallBase call , ReturnKind rk ) {
1382+ result = TSummaryReturnArgumentNode ( call , rk )
1383+ }
1384+
1385+ /** Gets the enclosing callable for summary node `sn`. */
1386+ DataFlowCallable getEnclosingCallable ( SummaryNode sn ) {
1387+ result = getSummarizedCallableAsDataFlowCallable ( sn .getSummarizedCallable ( ) )
1388+ or
1389+ exists ( FlowSummaryCallBase call |
1390+ sn = TSummaryReturnArgumentNode ( call , _) and
1391+ result = getSourceCallEnclosingCallable ( call )
1392+ )
1393+ }
1394+
13241395 class SourceOutputNode extends SummaryNode , TSourceOutputNode {
13251396 private SourceElement source_ ;
13261397 private SummaryNodeState state_ ;
@@ -1427,6 +1498,12 @@ module Make<
14271498 SummarizedCallable c , SummaryNodeState state , ParameterPosition pos
14281499 ) {
14291500 state .isInputState ( c , SummaryComponentStack:: argument ( pos ) )
1501+ or
1502+ exists ( ReturnKind rk |
1503+ relevantFlowSummaryPosition ( c , rk ) and
1504+ state .isInputState ( c , SummaryComponentStack:: return ( rk ) ) and
1505+ pos = getFlowSummaryParameterPosition ( rk )
1506+ )
14301507 }
14311508
14321509 /**
@@ -1560,6 +1637,9 @@ module Make<
15601637 )
15611638 }
15621639
1640+ /** Holds if return kind `rk` is a relevant return kind for flow summary modeling. */
1641+ predicate relevantFlowSummaryPosition ( ReturnKind rk ) { relevantFlowSummaryPosition ( _, rk ) }
1642+
15631643 /**
15641644 * Holds if flow is allowed to pass from the parameter at position `pos` of `c`,
15651645 * to a return node, and back out to the parameter.
@@ -1736,9 +1816,15 @@ module Make<
17361816 }
17371817
17381818 signature module StepsInputSig {
1819+ /** Gets the summary node represented by data-flow node `n`, if any. */
1820+ SummaryNode getSummaryNode ( Node n ) ;
1821+
17391822 /** Gets a call that targets summarized callable `sc`. */
17401823 DataFlowCall getACall ( SummarizedCallable sc ) ;
17411824
1825+ /** Gets the out node of kind `rk` for `call`, if any. */
1826+ default Node getSourceOutNode ( FlowSummaryCallBase call , ReturnKind rk ) { none ( ) }
1827+
17421828 /** Gets the enclosing callable of `source`. */
17431829 DataFlowCallable getSourceNodeEnclosingCallable ( SourceBase source ) ;
17441830
@@ -1765,7 +1851,7 @@ module Make<
17651851 * Holds if there is a local step from `pred` to `succ`, which is synthesized
17661852 * from a flow summary.
17671853 */
1768- predicate summaryLocalStep (
1854+ private predicate summaryLocalStepImpl (
17691855 SummaryNode pred , SummaryNode succ , boolean preservesValue , string model
17701856 ) {
17711857 exists (
@@ -1811,9 +1897,27 @@ module Make<
18111897 )
18121898 }
18131899
1900+ /** Holds if there is a local step between data-flow nodes synthesized from a flow summary. */
1901+ predicate summaryLocalStep ( Node pred , SummaryNode succ , boolean preservesValue , string model ) {
1902+ exists ( SummaryNode predSummary |
1903+ predSummary = StepsInput:: getSummaryNode ( pred ) and
1904+ summaryLocalStepImpl ( predSummary , succ , preservesValue , model )
1905+ )
1906+ or
1907+ exists (
1908+ FlowSummaryCallBase summaryCall , ReturnKind rk , SummarizedCallable sc ,
1909+ SummaryComponentStack output
1910+ |
1911+ pred = StepsInput:: getSourceOutNode ( summaryCall , rk ) and
1912+ summaryCall = getASourceCall ( sc ) and
1913+ summary ( sc , SummaryComponentStack:: return ( rk ) , output , preservesValue , model ) and
1914+ succ = TSummaryReturnArgumentNode ( summaryCall , rk )
1915+ )
1916+ }
1917+
18141918 /** Holds if the value of `succ` is uniquely determined by the value of `pred`. */
18151919 predicate summaryLocalMustFlowStep ( SummaryNode pred , SummaryNode succ ) {
1816- pred = unique( SummaryNode n1 | summaryLocalStep ( n1 , succ , true , _) )
1920+ pred = unique( SummaryNode n1 | summaryLocalStepImpl ( n1 , succ , true , _) )
18171921 }
18181922
18191923 /**
@@ -1935,7 +2039,7 @@ module Make<
19352039 or
19362040 exists ( SummaryNode mid , boolean clearsOrExpectsMid |
19372041 paramReachesLocal ( p , mid , clearsOrExpectsMid ) and
1938- summaryLocalStep ( mid , n , true , _) and
2042+ summaryLocalStepImpl ( mid , n , true , _) and
19392043 if
19402044 summaryClearsContent ( n , _) or
19412045 summaryExpectsContent ( n , _)
@@ -1993,7 +2097,7 @@ module Make<
19932097 */
19942098 predicate summaryThroughStepValue ( ArgNode arg , Node out , SummarizedCallable sc ) {
19952099 exists ( SummaryNode ret |
1996- summaryLocalStep ( summaryArgParamRetOut ( arg , ret , out , sc ) , ret , true , _)
2100+ summaryLocalStepImpl ( summaryArgParamRetOut ( arg , ret , out , sc ) , ret , true , _)
19972101 )
19982102 }
19992103
@@ -2006,7 +2110,7 @@ module Make<
20062110 */
20072111 predicate summaryThroughStepTaint ( ArgNode arg , Node out , SummarizedCallable sc ) {
20082112 exists ( SummaryNode ret |
2009- summaryLocalStep ( summaryArgParamRetOut ( arg , ret , out , sc ) , ret , false , _)
2113+ summaryLocalStepImpl ( summaryArgParamRetOut ( arg , ret , out , sc ) , ret , false , _)
20102114 )
20112115 }
20122116
@@ -2020,7 +2124,7 @@ module Make<
20202124 predicate summaryGetterStep ( ArgNode arg , ContentSet c , Node out , SummarizedCallable sc ) {
20212125 exists ( SummaryNode mid , SummaryNode ret |
20222126 summaryReadStep ( summaryArgParamRetOut ( arg , ret , out , sc ) , c , mid ) and
2023- summaryLocalStep ( mid , ret , _, _)
2127+ summaryLocalStepImpl ( mid , ret , _, _)
20242128 )
20252129 }
20262130
@@ -2033,7 +2137,7 @@ module Make<
20332137 */
20342138 predicate summarySetterStep ( ArgNode arg , ContentSet c , Node out , SummarizedCallable sc ) {
20352139 exists ( SummaryNode mid , SummaryNode ret |
2036- summaryLocalStep ( summaryArgParamRetOut ( arg , ret , out , sc ) , mid , _, _) and
2140+ summaryLocalStepImpl ( summaryArgParamRetOut ( arg , ret , out , sc ) , mid , _, _) and
20372141 summaryStoreStep ( mid , c , ret )
20382142 )
20392143 }
@@ -2749,9 +2853,11 @@ module Make<
27492853 key = "semmle.label" and val = n .toString ( )
27502854 }
27512855
2856+ private Node getNode ( SummaryNode sn ) { sn = StepsInput:: getSummaryNode ( result ) }
2857+
27522858 private predicate edgesComponent ( NodeOrCall a , NodeOrCall b , string value ) {
27532859 exists ( boolean preservesValue |
2754- PrivateSteps:: summaryLocalStep ( a .asNode ( ) , b .asNode ( ) , preservesValue , _) and
2860+ PrivateSteps:: summaryLocalStep ( getNode ( a .asNode ( ) ) , b .asNode ( ) , preservesValue , _) and
27552861 if preservesValue = true then value = "value" else value = "taint"
27562862 )
27572863 or
0 commit comments