From d326b3a91c67b386c61d7c06943b275d3418b12b Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 25 May 2022 18:25:58 +0000 Subject: [PATCH 01/11] Swift: global dataflow WIP --- swift/ql/lib/codeql/swift/dataflow/Ssa.qll | 6 +++ .../dataflow/internal/DataFlowDispatch.qll | 49 +++++++++---------- .../dataflow/internal/DataFlowPrivate.qll | 23 ++++++++- .../dataflow/dataflow/DataFlow.ql | 28 +++++++++++ 4 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql diff --git a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll index 9053428d4b0..fe5478014be 100644 --- a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll +++ b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll @@ -64,6 +64,12 @@ module Ssa { a = bb.getNode(i).getNode().asAstNode() and value.getNode().asAstNode() = a.getSource() ) + or + exists(VarDecl var, BasicBlock bb, int blockIndex, PatternBindingDecl pbd | + this.definesAt(var, bb, blockIndex) and + pbd.getAPattern() = bb.getNode(blockIndex).getNode() and + value.getNode() = var.getParentInitializer() + ) } } } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll index 0fe0acad457..5b47f41c46c 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll @@ -1,5 +1,6 @@ private import swift private import DataFlowPrivate +private import DataFlowPublic newtype TReturnKind = TNormalReturnKind() @@ -42,47 +43,35 @@ class DataFlowCallable extends TDataFlowCallable { * A call. This includes calls from source code, as well as call(back)s * inside library callables with a flow summary. */ -class DataFlowCall extends TDataFlowCall { +class DataFlowCall extends ExprNode { + DataFlowCall() { + this.asExpr() instanceof CallExpr + } + /** Gets the enclosing callable. */ DataFlowCallable getEnclosingCallable() { none() } - - /** Gets a textual representation of this call. */ - string toString() { none() } - - /** Gets the location of this call. */ - Location getLocation() { none() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries). - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } } cached private module Cached { cached - newtype TDataFlowCallable = TODO_TDataFlowCallable() - - cached - newtype TDataFlowCall = TODO_TDataFlowCall() + newtype TDataFlowCallable = TDataFlowFunc(FuncDecl func) /** Gets a viable run-time target for the call `call`. */ cached - DataFlowCallable viableCallable(DataFlowCall call) { none() } + DataFlowCallable viableCallable(DataFlowCall call) { + result = TDataFlowFunc(call.asExpr().(CallExpr).getStaticTarget()) + } cached - newtype TArgumentPosition = TODO_TArgumentPosition() + newtype TArgumentPosition = + TThisArgument() or + TPositionalArgument(int n) { n in [0 .. 100] } // we rely on default exprs generated in the caller for ordering. TODO: compute range properly. TODO: varargs? cached - newtype TParameterPosition = TODO_TParameterPosition() + newtype TParameterPosition = + TThisParameter() or + TPositionalParameter(int n) { n in [0 .. 100] } // TODO: compute range properly } import Cached @@ -111,6 +100,12 @@ class ArgumentPosition extends TArgumentPosition { string toString() { none() } } +class PositionalArgumentPosition extends ArgumentPosition, TPositionalArgument { + int getIndex() { + this = TPositionalArgument(result) + } +} + /** Holds if arguments at position `apos` match parameters at position `ppos`. */ pragma[inline] predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { none() } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index fc3321d2263..d60a7bc471a 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -31,12 +31,18 @@ private class ExprNodeImpl extends ExprNode, NodeImpl { override Location getLocationImpl() { result = expr.getLocation() } override string toStringImpl() { result = expr.toString() } + + override DataFlowCallable getEnclosingCallable() { result = TDataFlowFunc(expr.getScope()) } } private class SsaDefinitionNodeImpl extends SsaDefinitionNode, NodeImpl { override Location getLocationImpl() { result = def.getLocation() } override string toStringImpl() { result = def.toString() } + + override DataFlowCallable getEnclosingCallable() { + result = TDataFlowFunc(def.getBasicBlock().getScope()) + } } /** A collection of cached types and predicates to be evaluated in the same stage. */ @@ -103,7 +109,11 @@ private module ParameterNodes { override string toStringImpl() { result = param.toString() } override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { - none() // TODO + exists(FuncDecl f, int index | + c = TDataFlowFunc(f) and + f.getParam(index) = param and + pos = TPositionalParameter(index) + ) } } } @@ -119,7 +129,16 @@ abstract class ArgumentNode extends Node { final DataFlowCall getCall() { this.argumentOf(result, _) } } -private module ArgumentNodes { } +private module ArgumentNodes { + class NormalArgumentNode extends ExprNode, ArgumentNode { + NormalArgumentNode() { exists(CallExpr call | call.getAnArgument().getExpr() = this.asExpr()) } + + override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { + call.asExpr().(CallExpr).getArgument(pos.(PositionalArgumentPosition).getIndex()).getExpr() = + this.asExpr() + } + } +} import ArgumentNodes diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql new file mode 100644 index 00000000000..d2291e1636f --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql @@ -0,0 +1,28 @@ +import swift +import codeql.swift.dataflow.DataFlow +import DataFlow::PathGraph + +class TestConfiguration extends DataFlow::Configuration { + TestConfiguration() { this = "TestConfiguration" } + + override predicate isSource(DataFlow::Node src) { + src.asExpr().(CallExpr).getStaticTarget().getName() = "source" + } + + override predicate isSink(DataFlow::Node sink) { + exists(CallExpr sinkCall | + sinkCall.getStaticTarget().getName() = "sink" and + sinkCall.getAnArgument() = sink.asExpr() + ) + } + + override int explorationLimit() { result = 100 } +} + +from DataFlow::PartialPathNode src, DataFlow::PartialPathNode sink, TestConfiguration test +where + //test.isSource(src) and + // test.isSink(sink) and + //DataFlow::localFlow(src, sink) + test.hasPartialFlow(src, sink, _) +select src, sink From 9f64622f3121d2212c3f60767718154ea895fe80 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 25 May 2022 19:18:43 +0000 Subject: [PATCH 02/11] Swift: data flow configurations working --- swift/ql/lib/codeql/swift/dataflow/Ssa.qll | 4 ++-- .../swift/dataflow/internal/DataFlowPrivate.qll | 4 +++- .../swift/dataflow/internal/DataFlowPublic.qll | 2 +- .../dataflow/dataflow/DataFlow.expected | 14 ++++++++++++++ .../library-tests/dataflow/dataflow/DataFlow.ql | 9 +++------ .../dataflow/dataflow/LocalFlow.expected | 1 + 6 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected diff --git a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll index fe5478014be..b7a84caca28 100644 --- a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll +++ b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll @@ -67,8 +67,8 @@ module Ssa { or exists(VarDecl var, BasicBlock bb, int blockIndex, PatternBindingDecl pbd | this.definesAt(var, bb, blockIndex) and - pbd.getAPattern() = bb.getNode(blockIndex).getNode() and - value.getNode() = var.getParentInitializer() + pbd.getAPattern() = bb.getNode(blockIndex).getNode().asAstNode() and + value.getNode().asAstNode() = var.getParentInitializer() ) } } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index d60a7bc471a..1902400bff3 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -188,7 +188,9 @@ class DataFlowType extends TDataFlowType { } /** Gets the type of `n` used for type pruning. */ -DataFlowType getNodeType(NodeImpl n) { none() } +DataFlowType getNodeType(NodeImpl n) { + any() // return the singleton DataFlowType until we support type pruning for Swift +} /** Gets a string representation of a `DataFlowType`. */ string ppReprType(DataFlowType t) { result = t.toString() } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll index 70afd2651e1..815b967e094 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll @@ -98,7 +98,7 @@ class PostUpdateNode extends Node instanceof PostUpdateNodeImpl { } /** Gets a node corresponding to expression `e`. */ -ExprNode exprNode(DataFlowExpr e) { none() } +ExprNode exprNode(DataFlowExpr e) { result.asExpr() = e } /** * Gets the node corresponding to the value of parameter `p` at function entry. diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected new file mode 100644 index 00000000000..e531105365d --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -0,0 +1,14 @@ +edges +| test.swift:6:19:6:26 | CallExpr : | test.swift:7:15:7:15 | DeclRefExpr | +| test.swift:6:19:6:26 | CallExpr : | test.swift:9:15:9:15 | DeclRefExpr | +| test.swift:6:19:6:26 | CallExpr : | test.swift:10:15:10:15 | DeclRefExpr | +nodes +| test.swift:6:19:6:26 | CallExpr : | semmle.label | CallExpr : | +| test.swift:7:15:7:15 | DeclRefExpr | semmle.label | DeclRefExpr | +| test.swift:9:15:9:15 | DeclRefExpr | semmle.label | DeclRefExpr | +| test.swift:10:15:10:15 | DeclRefExpr | semmle.label | DeclRefExpr | +subpaths +#select +| test.swift:6:19:6:26 | CallExpr : | test.swift:7:15:7:15 | DeclRefExpr | +| test.swift:6:19:6:26 | CallExpr : | test.swift:9:15:9:15 | DeclRefExpr | +| test.swift:6:19:6:26 | CallExpr : | test.swift:10:15:10:15 | DeclRefExpr | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql index d2291e1636f..3144222a652 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql @@ -12,17 +12,14 @@ class TestConfiguration extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { exists(CallExpr sinkCall | sinkCall.getStaticTarget().getName() = "sink" and - sinkCall.getAnArgument() = sink.asExpr() + sinkCall.getAnArgument().getExpr() = sink.asExpr() ) } override int explorationLimit() { result = 100 } } -from DataFlow::PartialPathNode src, DataFlow::PartialPathNode sink, TestConfiguration test +from DataFlow::PathNode src, DataFlow::PathNode sink, TestConfiguration test where - //test.isSource(src) and - // test.isSink(sink) and - //DataFlow::localFlow(src, sink) - test.hasPartialFlow(src, sink, _) + test.hasFlowPath(src, sink) select src, sink diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 949f9ce1dc8..0169f82ab99 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -1,6 +1,7 @@ | file://:0:0:0:0 | Phi | test.swift:15:15:15:15 | DeclRefExpr | | file://:0:0:0:0 | Phi | test.swift:21:15:21:15 | DeclRefExpr | | test.swift:6:9:6:13 | WriteDef | test.swift:7:15:7:15 | DeclRefExpr | +| test.swift:6:19:6:26 | CallExpr | test.swift:6:9:6:13 | WriteDef | | test.swift:7:15:7:15 | DeclRefExpr | test.swift:8:10:8:10 | DeclRefExpr | | test.swift:8:5:8:10 | WriteDef | test.swift:10:15:10:15 | DeclRefExpr | | test.swift:8:10:8:10 | DeclRefExpr | test.swift:8:5:8:10 | WriteDef | From aa77ea6bef7f6730b4d49e9213f970963b1a2532 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 25 May 2022 19:24:15 +0000 Subject: [PATCH 03/11] Swift: minimal tests for interprocedural flow --- .../library-tests/dataflow/dataflow/test.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index d20fecb54d7..ae1135fb5d4 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -20,3 +20,19 @@ func intraprocedural_with_local_flow() -> Void { } sink(arg: t1) } + +func caller_source() -> Void { + callee_sink(x: source()) +} + +func callee_sink(x: Int) -> Void { + sink(arg: x) +} + +func callee_source() -> Int { + return source() +} + +func caller_sink() -> Void { + sink(arg: callee_source()) +} From 25c8b8141c33c997387216982c4a94a86eec9a15 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 26 May 2022 16:48:24 +0000 Subject: [PATCH 04/11] Swift: add params to CFG --- .../internal/ControlFlowElements.qll | 11 + .../internal/ControlFlowGraphImpl.qll | 25 +- .../controlflow/graph/Cfg.expected | 417 ++++++++++++++++-- 3 files changed, 402 insertions(+), 51 deletions(-) diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowElements.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowElements.qll index 2a12d688ac8..6536e438cc2 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowElements.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowElements.qll @@ -3,6 +3,7 @@ private import swift cached newtype TControlFlowElement = TAstElement(AstNode n) or + TFuncDeclElement(AbstractFunctionDecl func) { func.hasBody() } or TPropertyGetterElement(Decl accessor, Expr ref) { isPropertyGetterElement(accessor, ref) } or TPropertySetterElement(AccessorDecl accessor, AssignExpr assign) { isPropertySetterElement(accessor, assign) @@ -161,3 +162,13 @@ class PropertyObserverElement extends ControlFlowElement, TPropertyObserverEleme AssignExpr getAssignExpr() { result = assign } } + + +class FuncDeclElement extends ControlFlowElement, TFuncDeclElement { + AbstractFunctionDecl func; + FuncDeclElement() { this = TFuncDeclElement(func) } + + override string toString() { result = func.toString() } + + override Location getLocation() { result = func.getLocation() } +} \ No newline at end of file diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll index cc89ab2f836..44a7ea0c748 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll @@ -48,15 +48,15 @@ module CfgScope { private class BodyStmtCallableScope extends Range_ instanceof AbstractFunctionDecl { final override predicate entry(ControlFlowElement first) { - exists(Stmts::BraceStmtTree tree | - tree.getAst() = super.getBody() and - tree.firstInner(first) + exists(Decls::FuncDeclTree tree | + tree.getAst() = this and + first = tree ) } final override predicate exit(ControlFlowElement last, Completion c) { - exists(Stmts::BraceStmtTree tree | - tree.getAst() = super.getBody() and + exists(Decls::FuncDeclTree tree | + tree.getAst() = this and tree.last(last, c) ) } @@ -884,6 +884,21 @@ module Decls { ) } } + + class FuncDeclTree extends StandardPreOrderTree, TFuncDeclElement { + AbstractFunctionDecl ast; + + FuncDeclTree() { this = TFuncDeclElement(ast) } + + AbstractFunctionDecl getAst() { result = ast } + + final override ControlFlowElement getChildElement(int i) { + result.asAstNode() = ast.getParam(i) + or + result.asAstNode() = ast.getBody() and + i = ast.getNumberOfParams() + } + } } module Exprs { diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index 181ae94bf32..9df24871348 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -1,7 +1,10 @@ cfg.swift: -# 5| enter ConcreteFuncDecl +# 5| ConcreteFuncDecl #-----| -> IntegerLiteralExpr +# 5| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + # 5| exit ConcreteFuncDecl # 5| exit ConcreteFuncDecl (normal) @@ -13,14 +16,20 @@ cfg.swift: # 5| IntegerLiteralExpr #-----| -> ReturnStmt +# 15| ConcreteFuncDecl +#-----| -> ParamDecl + # 15| enter ConcreteFuncDecl -#-----| -> DeclRefExpr +#-----| -> ConcreteFuncDecl # 15| exit ConcreteFuncDecl # 15| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 15| ParamDecl +#-----| -> DeclRefExpr + # 15| ReturnStmt #-----| return -> exit ConcreteFuncDecl (normal) @@ -43,14 +52,20 @@ cfg.swift: # 15| IntegerLiteralExpr #-----| -> BinaryExpr +# 17| ConcreteFuncDecl +#-----| -> ParamDecl + # 17| enter ConcreteFuncDecl -#-----| -> GuardStmt +#-----| -> ConcreteFuncDecl # 17| exit ConcreteFuncDecl # 17| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 17| ParamDecl +#-----| -> GuardStmt + # 18| GuardStmt #-----| -> DeclRefExpr @@ -155,14 +170,20 @@ cfg.swift: # 22| IntegerLiteralExpr #-----| -> BinaryExpr +# 26| ConcreteFuncDecl +#-----| -> ParamDecl + # 26| enter ConcreteFuncDecl -#-----| -> DoCatchStmt +#-----| -> ConcreteFuncDecl # 26| exit ConcreteFuncDecl # 26| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 26| ParamDecl +#-----| -> DoCatchStmt + # 27| DoCatchStmt #-----| -> DeclRefExpr @@ -343,28 +364,48 @@ cfg.swift: # 42| IntegerLiteralExpr #-----| -> ReturnStmt +# 45| ConcreteFuncDecl +#-----| -> ParamDecl + # 45| enter ConcreteFuncDecl -#-----| -> ClosureExpr +#-----| -> ConcreteFuncDecl # 45| exit ConcreteFuncDecl # 45| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 45| ParamDecl +#-----| -> ClosureExpr + # 46| ReturnStmt #-----| return -> exit ConcreteFuncDecl (normal) # 46| ClosureExpr #-----| -> ReturnStmt +# 51| ConcreteFuncDecl +#-----| -> ParamDecl + +# 51| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + +# 51| ParamDecl + +# 52| ConcreteFuncDecl +#-----| -> ParamDecl + # 52| enter ConcreteFuncDecl -#-----| -> DeclRefExpr +#-----| -> ConcreteFuncDecl # 52| exit ConcreteFuncDecl # 52| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 52| ParamDecl +#-----| -> DeclRefExpr + # 53| ReturnStmt #-----| return -> exit ConcreteFuncDecl (normal) @@ -387,23 +428,32 @@ cfg.swift: # 53| DeclRefExpr #-----| -> BinaryExpr +# 58| ConcreteFuncDecl +#-----| -> ParamDecl + # 58| enter ConcreteFuncDecl -#-----| -> ClosureExpr +#-----| -> ConcreteFuncDecl # 58| exit ConcreteFuncDecl # 58| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 58| ParamDecl +#-----| -> ClosureExpr + # 59| ReturnStmt #-----| return -> exit ConcreteFuncDecl (normal) # 59| ClosureExpr #-----| -> ReturnStmt -# 64| enter ConcreteFuncDecl +# 64| ConcreteFuncDecl #-----| -> NamedPattern +# 64| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + # 64| exit ConcreteFuncDecl # 64| exit ConcreteFuncDecl (normal) @@ -481,14 +531,20 @@ cfg.swift: # 67| IntegerLiteralExpr #-----| -> CallExpr +# 70| ConcreteFuncDecl +#-----| -> ParamDecl + # 70| enter ConcreteFuncDecl -#-----| -> NamedPattern +#-----| -> ConcreteFuncDecl # 70| exit ConcreteFuncDecl # 70| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 70| ParamDecl +#-----| -> NamedPattern + # 71| PatternBindingDecl #-----| -> ConcreteVarDecl @@ -525,9 +581,12 @@ cfg.swift: # 72| LoadExpr #-----| -> ReturnStmt -# 75| enter ConcreteFuncDecl +# 75| ConcreteFuncDecl #-----| -> NamedPattern +# 75| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + # 75| exit ConcreteFuncDecl # 75| exit ConcreteFuncDecl (normal) @@ -608,9 +667,12 @@ cfg.swift: # 78| ForceValueExpr #-----| -> BinaryExpr -# 81| enter ConcreteFuncDecl +# 81| ConcreteFuncDecl #-----| -> NamedPattern +# 81| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + # 82| PatternBindingDecl #-----| -> ConcreteVarDecl @@ -622,14 +684,20 @@ cfg.swift: # 82| IntegerLiteralExpr #-----| -> PatternBindingDecl +# 84| ConcreteFuncDecl +#-----| -> ParamDecl + # 84| enter ConcreteFuncDecl -#-----| -> DeclRefExpr +#-----| -> ConcreteFuncDecl # 84| exit ConcreteFuncDecl # 84| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 84| ParamDecl +#-----| -> DeclRefExpr + # 85| DeclRefExpr #-----| -> DeclRefExpr @@ -658,14 +726,20 @@ cfg.swift: # 85| IntegerLiteralExpr #-----| -> BinaryExpr +# 88| ConcreteFuncDecl +#-----| -> ParamDecl + # 88| enter ConcreteFuncDecl -#-----| -> DeclRefExpr +#-----| -> ConcreteFuncDecl # 88| exit ConcreteFuncDecl # 88| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 88| ParamDecl +#-----| -> DeclRefExpr + # 89| DeclRefExpr #-----| -> NilLiteralExpr @@ -675,21 +749,44 @@ cfg.swift: # 89| NilLiteralExpr #-----| -> AssignExpr +# 98| BraceStmt +#-----| -> exit DestructorDecl (normal) + +# 98| DestructorDecl +#-----| -> BraceStmt + +# 98| enter DestructorDecl +#-----| -> DestructorDecl + +# 98| exit DestructorDecl + +# 98| exit DestructorDecl (normal) +#-----| -> exit DestructorDecl + +# 99| AccessorDecl + # 99| enter AccessorDecl +#-----| -> AccessorDecl # 99| exit AccessorDecl # 99| exit AccessorDecl (normal) #-----| -> exit AccessorDecl +# 100| ConstructorDecl +#-----| -> ParamDecl + # 100| enter ConstructorDecl -#-----| -> DeclRefExpr +#-----| -> ConstructorDecl # 100| exit ConstructorDecl # 100| exit ConstructorDecl (normal) #-----| -> exit ConstructorDecl +# 100| ParamDecl +#-----| -> DeclRefExpr + # 101| DeclRefExpr #-----| -> MemberRefExpr @@ -705,9 +802,12 @@ cfg.swift: # 102| ReturnStmt #-----| return -> exit ConstructorDecl (normal) -# 104| enter ConcreteFuncDecl +# 104| ConcreteFuncDecl #-----| -> DeclRefExpr +# 104| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + # 104| exit ConcreteFuncDecl # 104| exit ConcreteFuncDecl (normal) @@ -722,14 +822,26 @@ cfg.swift: # 105| getter for MemberRefExpr #-----| -> ReturnStmt +# 109| ConcreteFuncDecl +#-----| -> ParamDecl + # 109| enter ConcreteFuncDecl -#-----| -> NamedPattern +#-----| -> ConcreteFuncDecl # 109| exit ConcreteFuncDecl # 109| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 109| ParamDecl +#-----| -> ParamDecl + +# 109| ParamDecl +#-----| -> ParamDecl + +# 109| ParamDecl +#-----| -> NamedPattern + # 110| PatternBindingDecl #-----| -> ConcreteVarDecl @@ -1172,14 +1284,20 @@ cfg.swift: # 134| DeclRefExpr #-----| -> TBD (DotSelfExpr) +# 137| ConcreteFuncDecl +#-----| -> ParamDecl + # 137| enter ConcreteFuncDecl -#-----| -> DeclRefExpr +#-----| -> ConcreteFuncDecl # 137| exit ConcreteFuncDecl # 137| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 137| ParamDecl +#-----| -> DeclRefExpr + # 138| ForEachStmt #-----| non-empty -> AnyPattern #-----| empty -> SwitchStmt @@ -1275,14 +1393,20 @@ cfg.swift: # 147| BooleanLiteralExpr #-----| -> ReturnStmt +# 163| ConcreteFuncDecl +#-----| -> ParamDecl + # 163| enter ConcreteFuncDecl -#-----| -> DeferStmt +#-----| -> ConcreteFuncDecl # 163| exit ConcreteFuncDecl # 163| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 163| ParamDecl +#-----| -> DeferStmt + # 165| DeferStmt #-----| -> DeferStmt @@ -1391,14 +1515,20 @@ cfg.swift: # 176| VarargExpansionExpr #-----| -> DefaultArgumentExpr +# 181| ConcreteFuncDecl +#-----| -> ParamDecl + # 181| enter ConcreteFuncDecl -#-----| -> IfStmt +#-----| -> ConcreteFuncDecl # 181| exit ConcreteFuncDecl # 181| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 181| ParamDecl +#-----| -> IfStmt + # 182| IfStmt #-----| -> DeclRefExpr @@ -1590,14 +1720,20 @@ cfg.swift: # 189| VarargExpansionExpr #-----| -> DefaultArgumentExpr +# 193| ConcreteFuncDecl +#-----| -> ParamDecl + # 193| enter ConcreteFuncDecl -#-----| -> IfStmt +#-----| -> ConcreteFuncDecl # 193| exit ConcreteFuncDecl # 193| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 193| ParamDecl +#-----| -> IfStmt + # 194| IfStmt #-----| -> DeclRefExpr @@ -1620,14 +1756,20 @@ cfg.swift: # 197| IntegerLiteralExpr #-----| -> ReturnStmt +# 200| ConcreteFuncDecl +#-----| -> ParamDecl + # 200| enter ConcreteFuncDecl -#-----| -> IfStmt +#-----| -> ConcreteFuncDecl # 200| exit ConcreteFuncDecl # 200| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 200| ParamDecl +#-----| -> IfStmt + # 201| IfStmt #-----| -> DeclRefExpr @@ -1748,14 +1890,26 @@ cfg.swift: # 207| LoadExpr #-----| -> ReturnStmt +# 210| ConcreteFuncDecl +#-----| -> ParamDecl + # 210| enter ConcreteFuncDecl -#-----| -> DeclRefExpr +#-----| -> ConcreteFuncDecl # 210| exit ConcreteFuncDecl # 210| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 210| ParamDecl +#-----| -> ParamDecl + +# 210| ParamDecl +#-----| -> ParamDecl + +# 210| ParamDecl +#-----| -> DeclRefExpr + # 211| ReturnStmt #-----| return -> exit ConcreteFuncDecl (normal) @@ -1792,14 +1946,20 @@ cfg.swift: # 211| StringLiteralExpr #-----| -> IfExpr +# 214| ConcreteFuncDecl +#-----| -> ParamDecl + # 214| enter ConcreteFuncDecl -#-----| -> IfStmt +#-----| -> ConcreteFuncDecl # 214| exit ConcreteFuncDecl # 214| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 214| ParamDecl +#-----| -> IfStmt + # 215| IfStmt #-----| -> DeclRefExpr @@ -1838,9 +1998,12 @@ cfg.swift: # 219| StringLiteralExpr #-----| -> ReturnStmt -# 223| enter ConcreteFuncDecl +# 223| ConcreteFuncDecl #-----| -> IfStmt +# 223| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + # 223| exit ConcreteFuncDecl # 223| exit ConcreteFuncDecl (normal) @@ -1883,14 +2046,20 @@ cfg.swift: # 225| VarargExpansionExpr #-----| -> DefaultArgumentExpr +# 229| ConcreteFuncDecl +#-----| -> ParamDecl + # 229| enter ConcreteFuncDecl -#-----| -> IfStmt +#-----| -> ConcreteFuncDecl # 229| exit ConcreteFuncDecl # 229| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 229| ParamDecl +#-----| -> IfStmt + # 230| IfStmt #-----| -> DeclRefExpr @@ -1953,14 +2122,23 @@ cfg.swift: # 234| VarargExpansionExpr #-----| -> DefaultArgumentExpr +# 237| ConcreteFuncDecl +#-----| -> ParamDecl + # 237| enter ConcreteFuncDecl -#-----| -> IfStmt +#-----| -> ConcreteFuncDecl # 237| exit ConcreteFuncDecl # 237| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 237| ParamDecl +#-----| -> ParamDecl + +# 237| ParamDecl +#-----| -> IfStmt + # 238| IfStmt #-----| -> DeclRefExpr @@ -2011,14 +2189,23 @@ cfg.swift: # 239| VarargExpansionExpr #-----| -> DefaultArgumentExpr +# 243| ConcreteFuncDecl +#-----| -> ParamDecl + # 243| enter ConcreteFuncDecl -#-----| -> NamedPattern +#-----| -> ConcreteFuncDecl # 243| exit ConcreteFuncDecl # 243| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 243| ParamDecl +#-----| -> ParamDecl + +# 243| ParamDecl +#-----| -> NamedPattern + # 244| PatternBindingDecl #-----| -> ConcreteVarDecl @@ -2467,23 +2654,35 @@ cfg.swift: # 259| DeclRefExpr #-----| -> BinaryExpr +# 262| ConcreteFuncDecl +#-----| -> ParamDecl + # 262| enter ConcreteFuncDecl -#-----| -> InterpolatedStringLiteralExpr +#-----| -> ConcreteFuncDecl # 262| exit ConcreteFuncDecl # 262| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 262| ParamDecl +#-----| -> ParamDecl + +# 262| ParamDecl +#-----| -> InterpolatedStringLiteralExpr + # 263| ReturnStmt #-----| return -> exit ConcreteFuncDecl (normal) # 263| InterpolatedStringLiteralExpr #-----| -> ReturnStmt -# 266| enter ConcreteFuncDecl +# 266| ConcreteFuncDecl #-----| -> NamedPattern +# 266| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + # 266| exit ConcreteFuncDecl # 266| exit ConcreteFuncDecl (normal) @@ -3678,14 +3877,20 @@ cfg.swift: # 296| IntegerLiteralExpr #-----| -> getter for SubscriptExpr +# 299| ConcreteFuncDecl +#-----| -> ParamDecl + # 299| enter ConcreteFuncDecl -#-----| -> WhileStmt +#-----| -> ConcreteFuncDecl # 299| exit ConcreteFuncDecl # 299| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 299| ParamDecl +#-----| -> WhileStmt + # 300| WhileStmt #-----| -> DeclRefExpr @@ -3765,14 +3970,20 @@ cfg.swift: # 302| IntegerLiteralExpr #-----| -> BinaryExpr +# 306| ConcreteFuncDecl +#-----| -> ParamDecl + # 306| enter ConcreteFuncDecl -#-----| -> WhileStmt +#-----| -> ConcreteFuncDecl # 306| exit ConcreteFuncDecl # 306| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 306| ParamDecl +#-----| -> WhileStmt + # 307| WhileStmt #-----| -> DeclRefExpr @@ -3965,14 +4176,20 @@ cfg.swift: # 318| VarargExpansionExpr #-----| -> DefaultArgumentExpr +# 321| ConcreteFuncDecl +#-----| -> ParamDecl + # 321| enter ConcreteFuncDecl -#-----| -> WhileStmt +#-----| -> ConcreteFuncDecl # 321| exit ConcreteFuncDecl # 321| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 321| ParamDecl +#-----| -> WhileStmt + # 322| WhileStmt #-----| -> DeclRefExpr @@ -4195,14 +4412,20 @@ cfg.swift: # 334| VarargExpansionExpr #-----| -> DefaultArgumentExpr +# 338| ConcreteFuncDecl +#-----| -> ParamDecl + # 338| enter ConcreteFuncDecl -#-----| -> RepeatWhileStmt +#-----| -> ConcreteFuncDecl # 338| exit ConcreteFuncDecl # 338| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 338| ParamDecl +#-----| -> RepeatWhileStmt + # 339| RepeatWhileStmt #-----| -> DeclRefExpr @@ -4279,9 +4502,12 @@ cfg.swift: # 342| IntegerLiteralExpr #-----| -> BinaryExpr -# 345| enter ConcreteFuncDecl +# 345| ConcreteFuncDecl #-----| -> NamedPattern +# 345| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + # 345| exit ConcreteFuncDecl # 345| exit ConcreteFuncDecl (normal) @@ -4353,21 +4579,44 @@ cfg.swift: # 348| IntegerLiteralExpr #-----| -> BinaryExpr +# 352| BraceStmt +#-----| -> exit DestructorDecl (normal) + +# 352| DestructorDecl +#-----| -> BraceStmt + +# 352| enter DestructorDecl +#-----| -> DestructorDecl + +# 352| exit DestructorDecl + +# 352| exit DestructorDecl (normal) +#-----| -> exit DestructorDecl + +# 353| AccessorDecl + # 353| enter AccessorDecl +#-----| -> AccessorDecl # 353| exit AccessorDecl # 353| exit AccessorDecl (normal) #-----| -> exit AccessorDecl +# 354| ConstructorDecl +#-----| -> ParamDecl + # 354| enter ConstructorDecl -#-----| -> DeclRefExpr +#-----| -> ConstructorDecl # 354| exit ConstructorDecl # 354| exit ConstructorDecl (normal) #-----| -> exit ConstructorDecl +# 354| ParamDecl +#-----| -> DeclRefExpr + # 355| DeclRefExpr #-----| -> MemberRefExpr @@ -4383,9 +4632,12 @@ cfg.swift: # 356| ReturnStmt #-----| return -> exit ConstructorDecl (normal) -# 358| enter ConcreteFuncDecl +# 358| ConcreteFuncDecl #-----| -> DeclRefExpr +# 358| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + # 358| exit ConcreteFuncDecl # 358| exit ConcreteFuncDecl (normal) @@ -4400,14 +4652,20 @@ cfg.swift: # 359| getter for MemberRefExpr #-----| -> ReturnStmt +# 363| ConcreteFuncDecl +#-----| -> ParamDecl + # 363| enter ConcreteFuncDecl -#-----| -> DeclRefExpr +#-----| -> ConcreteFuncDecl # 363| exit ConcreteFuncDecl # 363| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 363| ParamDecl +#-----| -> DeclRefExpr + # 364| ReturnStmt #-----| return -> exit ConcreteFuncDecl (normal) @@ -4446,14 +4704,23 @@ cfg.swift: # 364| DeclRefExpr #-----| -> DeclRefExpr +# 367| ConcreteFuncDecl +#-----| -> ParamDecl + # 367| enter ConcreteFuncDecl -#-----| -> NamedPattern +#-----| -> ConcreteFuncDecl # 367| exit ConcreteFuncDecl # 367| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 367| ParamDecl +#-----| -> ParamDecl + +# 367| ParamDecl +#-----| -> NamedPattern + # 368| ReturnStmt #-----| return -> exit ConcreteFuncDecl (normal) @@ -4497,14 +4764,20 @@ cfg.swift: # 368| StringLiteralExpr #-----| -> PatternBindingDecl +# 373| ConcreteFuncDecl +#-----| -> ParamDecl + # 373| enter ConcreteFuncDecl -#-----| -> DeclRefExpr +#-----| -> ConcreteFuncDecl # 373| exit ConcreteFuncDecl # 373| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 373| ParamDecl +#-----| -> DeclRefExpr + # 374| ReturnStmt #-----| return -> exit ConcreteFuncDecl (normal) @@ -4580,12 +4853,18 @@ cfg.swift: # 374| IntegerLiteralExpr #-----| -> TupleExpr +# 377| BraceStmt +#-----| -> exit DestructorDecl (normal) + # 377| CallExpr #-----| exception -> exit ConstructorDecl (normal) # 377| DeclRefExpr #-----| -> StringLiteralExpr +# 377| DestructorDecl +#-----| -> BraceStmt + # 377| MagicIdentifierLiteralExpr #-----| -> MagicIdentifierLiteralExpr @@ -4601,17 +4880,30 @@ cfg.swift: # 377| StringLiteralExpr #-----| -> MagicIdentifierLiteralExpr +# 377| enter DestructorDecl +#-----| -> DestructorDecl + +# 377| exit DestructorDecl + +# 377| exit DestructorDecl (normal) +#-----| -> exit DestructorDecl + +# 377| ConstructorDecl + # 377| enter ConstructorDecl -#-----| -> DeclRefExpr +#-----| -> ConstructorDecl # 377| exit ConstructorDecl # 377| exit ConstructorDecl (normal) #-----| -> exit ConstructorDecl -# 378| enter ConstructorDecl +# 378| ConstructorDecl #-----| -> TBD (OtherConstructorDeclRefExpr) +# 378| enter ConstructorDecl +#-----| -> ConstructorDecl + # 378| exit ConstructorDecl # 378| exit ConstructorDecl (normal) @@ -4638,14 +4930,20 @@ cfg.swift: # 380| ReturnStmt #-----| return -> exit ConstructorDecl (normal) +# 383| ConcreteFuncDecl +#-----| -> ParamDecl + # 383| enter ConcreteFuncDecl -#-----| -> DoStmt +#-----| -> ConcreteFuncDecl # 383| exit ConcreteFuncDecl # 383| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 383| ParamDecl +#-----| -> DoStmt + # 384| DoStmt #-----| -> DeclRefExpr @@ -4686,15 +4984,27 @@ cfg.swift: # 386| VarargExpansionExpr #-----| -> DefaultArgumentExpr +# 394| AccessorDecl + +# 394| AccessorDecl +#-----| -> ParamDecl + +# 394| AccessorDecl +#-----| -> TBD (YieldStmt) + +# 394| ParamDecl + # 394| TBD (YieldStmt) #-----| -> exit AccessorDecl (normal) # 394| enter AccessorDecl +#-----| -> AccessorDecl # 394| enter AccessorDecl +#-----| -> AccessorDecl # 394| enter AccessorDecl -#-----| -> TBD (YieldStmt) +#-----| -> AccessorDecl # 394| exit AccessorDecl @@ -4711,8 +5021,11 @@ cfg.swift: # 394| exit AccessorDecl (normal) #-----| -> exit AccessorDecl +# 395| ConstructorDecl +#-----| -> DeclRefExpr + # 395| enter ConstructorDecl -#-----| -> DeclRefExpr +#-----| -> ConstructorDecl # 395| exit ConstructorDecl @@ -4734,9 +5047,12 @@ cfg.swift: # 397| ReturnStmt #-----| return -> exit ConstructorDecl (normal) -# 399| enter DestructorDecl +# 399| DestructorDecl #-----| -> DeclRefExpr +# 399| enter DestructorDecl +#-----| -> DestructorDecl + # 399| exit DestructorDecl # 399| exit DestructorDecl (normal) @@ -4754,14 +5070,23 @@ cfg.swift: # 400| IntegerLiteralExpr #-----| -> AssignExpr +# 404| ConcreteFuncDecl +#-----| -> ParamDecl + # 404| enter ConcreteFuncDecl -#-----| -> StringLiteralExpr +#-----| -> ConcreteFuncDecl # 404| exit ConcreteFuncDecl # 404| exit ConcreteFuncDecl (normal) #-----| -> exit ConcreteFuncDecl +# 404| ParamDecl +#-----| -> ParamDecl + +# 404| ParamDecl +#-----| -> StringLiteralExpr + # 405| ReturnStmt #-----| return -> exit ConcreteFuncDecl (normal) From ae6d16a40fb324fa635a1b231a61dc99c61f2f2a Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 26 May 2022 16:53:42 +0000 Subject: [PATCH 05/11] Swift: flow into callees via params --- .../swift/dataflow/internal/DataFlowDispatch.qll | 14 +++++++++++++- .../swift/dataflow/internal/DataFlowPrivate.qll | 13 ++++++++++--- .../swift/dataflow/internal/DataFlowPublic.qll | 2 +- .../swift/dataflow/internal/SsaImplSpecific.qll | 4 ++++ .../dataflow/dataflow/DataFlow.expected | 11 +++++++++++ .../dataflow/dataflow/LocalFlow.expected | 2 ++ 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll index 5b47f41c46c..889f85d7450 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll @@ -94,6 +94,13 @@ class ParameterPosition extends TParameterPosition { string toString() { none() } } +class PositionalParameterPosition extends ParameterPosition, TPositionalParameter { + int getIndex() { + this = TPositionalParameter(result) + } +} + + /** An argument position. */ class ArgumentPosition extends TArgumentPosition { /** Gets a textual representation of this position. */ @@ -108,4 +115,9 @@ class PositionalArgumentPosition extends ArgumentPosition, TPositionalArgument { /** Holds if arguments at position `apos` match parameters at position `ppos`. */ pragma[inline] -predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { none() } +predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { + ppos instanceof TThisParameter and + apos instanceof TThisArgument + or + ppos.(PositionalParameterPosition).getIndex() = apos.(PositionalArgumentPosition).getIndex() +} diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 1902400bff3..99fe045dfb9 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -3,6 +3,7 @@ private import DataFlowPublic private import DataFlowDispatch private import codeql.swift.controlflow.CfgNodes private import codeql.swift.dataflow.Ssa +private import codeql.swift.controlflow.BasicBlocks /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallable() } @@ -51,7 +52,6 @@ private module Cached { cached newtype TNode = TExprNode(ExprCfgNode e) or - TNormalParameterNode(ParamDecl p) or TSsaDefinitionNode(Ssa::Definition def) private predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) { @@ -99,10 +99,15 @@ private module ParameterNodes { predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { none() } } - class NormalParameterNode extends ParameterNodeImpl, TNormalParameterNode { + class NormalParameterNode extends ParameterNodeImpl, SsaDefinitionNode { ParamDecl param; - NormalParameterNode() { this = TNormalParameterNode(param) } + NormalParameterNode() { + exists(BasicBlock bb, int i | + super.asDefinition().definesAt(param, bb, i) and + bb.getNode(i).getNode().asAstNode() = param + ) + } override Location getLocationImpl() { result = param.getLocation() } @@ -115,6 +120,8 @@ private module ParameterNodes { pos = TPositionalParameter(index) ) } + + override DataFlowCallable getEnclosingCallable() { isParameterOf(result, _) } } } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll index 815b967e094..67a184193d0 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll @@ -69,7 +69,7 @@ class ExprNode extends Node, TExprNode { * The value of a parameter at function entry, viewed as a node in a data * flow graph. */ -class ParameterNode extends Node, TNormalParameterNode instanceof ParameterNodeImpl { } +class ParameterNode extends Node, SsaDefinitionNode instanceof ParameterNodeImpl { } /** */ diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/SsaImplSpecific.qll b/swift/ql/lib/codeql/swift/dataflow/internal/SsaImplSpecific.qll index bd7373935aa..458e0b3a2e6 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/SsaImplSpecific.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/SsaImplSpecific.qll @@ -27,6 +27,10 @@ predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) v.getParentPattern() = pattern and certain = true ) + or + v instanceof ParamDecl and + bb.getNode(i).getNode().asAstNode() = v and + certain = true } private predicate isLValue(DeclRefExpr ref) { any(AssignExpr assign).getDest() = ref } diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index e531105365d..2c1e6f4f924 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -2,13 +2,24 @@ edges | test.swift:6:19:6:26 | CallExpr : | test.swift:7:15:7:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr : | test.swift:9:15:9:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr : | test.swift:10:15:10:15 | DeclRefExpr | +| test.swift:25:20:25:27 | CallExpr : | test.swift:28:18:28:21 | ParamDecl : | +| test.swift:25:20:25:27 | CallExpr : | test.swift:28:18:28:21 | WriteDef : | +| test.swift:28:18:28:21 | ParamDecl : | test.swift:29:15:29:15 | DeclRefExpr | +| test.swift:28:18:28:21 | WriteDef : | test.swift:29:15:29:15 | DeclRefExpr | nodes | test.swift:6:19:6:26 | CallExpr : | semmle.label | CallExpr : | | test.swift:7:15:7:15 | DeclRefExpr | semmle.label | DeclRefExpr | | test.swift:9:15:9:15 | DeclRefExpr | semmle.label | DeclRefExpr | | test.swift:10:15:10:15 | DeclRefExpr | semmle.label | DeclRefExpr | +| test.swift:25:20:25:27 | CallExpr : | semmle.label | CallExpr : | +| test.swift:28:18:28:21 | ParamDecl : | semmle.label | ParamDecl : | +| test.swift:28:18:28:21 | ParamDecl : | semmle.label | WriteDef : | +| test.swift:28:18:28:21 | WriteDef : | semmle.label | ParamDecl : | +| test.swift:28:18:28:21 | WriteDef : | semmle.label | WriteDef : | +| test.swift:29:15:29:15 | DeclRefExpr | semmle.label | DeclRefExpr | subpaths #select | test.swift:6:19:6:26 | CallExpr : | test.swift:7:15:7:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr : | test.swift:9:15:9:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr : | test.swift:10:15:10:15 | DeclRefExpr | +| test.swift:25:20:25:27 | CallExpr : | test.swift:29:15:29:15 | DeclRefExpr | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 0169f82ab99..611ef065883 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -13,3 +13,5 @@ | test.swift:17:10:17:10 | IntegerLiteralExpr | test.swift:17:5:17:10 | WriteDef | | test.swift:19:14:19:14 | DeclRefExpr | test.swift:19:9:19:14 | WriteDef | | test.swift:19:14:19:14 | DeclRefExpr | test.swift:19:14:19:14 | DeclRefExpr | +| test.swift:28:18:28:21 | ParamDecl | test.swift:29:15:29:15 | DeclRefExpr | +| test.swift:28:18:28:21 | WriteDef | test.swift:29:15:29:15 | DeclRefExpr | From 81ac6480658066fec183f6e1bf6da6845a4722ef Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 26 May 2022 16:58:53 +0000 Subject: [PATCH 06/11] Swift: flow out of calls via return statements --- .../dataflow/internal/DataFlowPrivate.qll | 22 +++++++++++++++++-- .../dataflow/dataflow/DataFlow.expected | 4 ++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 99fe045dfb9..e0853d28e28 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -155,7 +155,19 @@ abstract class ReturnNode extends Node { abstract ReturnKind getKind(); } -private module ReturnNodes { } +private module ReturnNodes { + class ReturnReturnNode extends ReturnNode, ExprNode { + ReturnReturnNode() { + exists(ReturnStmt stmt | + stmt.getResult() = this.asExpr() + ) + } + + override ReturnKind getKind() { + result instanceof NormalReturnKind + } + } +} import ReturnNodes @@ -165,7 +177,13 @@ abstract class OutNode extends Node { abstract DataFlowCall getCall(ReturnKind kind); } -private module OutNodes { } +private module OutNodes { + class CallOutNode extends OutNode, DataFlowCall { + override DataFlowCall getCall(ReturnKind kind) { + result = this and kind instanceof NormalReturnKind + } + } +} import OutNodes diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index 2c1e6f4f924..164674b22a8 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -6,6 +6,7 @@ edges | test.swift:25:20:25:27 | CallExpr : | test.swift:28:18:28:21 | WriteDef : | | test.swift:28:18:28:21 | ParamDecl : | test.swift:29:15:29:15 | DeclRefExpr | | test.swift:28:18:28:21 | WriteDef : | test.swift:29:15:29:15 | DeclRefExpr | +| test.swift:33:12:33:19 | CallExpr : | test.swift:37:15:37:29 | CallExpr | nodes | test.swift:6:19:6:26 | CallExpr : | semmle.label | CallExpr : | | test.swift:7:15:7:15 | DeclRefExpr | semmle.label | DeclRefExpr | @@ -17,9 +18,12 @@ nodes | test.swift:28:18:28:21 | WriteDef : | semmle.label | ParamDecl : | | test.swift:28:18:28:21 | WriteDef : | semmle.label | WriteDef : | | test.swift:29:15:29:15 | DeclRefExpr | semmle.label | DeclRefExpr | +| test.swift:33:12:33:19 | CallExpr : | semmle.label | CallExpr : | +| test.swift:37:15:37:29 | CallExpr | semmle.label | CallExpr | subpaths #select | test.swift:6:19:6:26 | CallExpr : | test.swift:7:15:7:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr : | test.swift:9:15:9:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr : | test.swift:10:15:10:15 | DeclRefExpr | | test.swift:25:20:25:27 | CallExpr : | test.swift:29:15:29:15 | DeclRefExpr | +| test.swift:33:12:33:19 | CallExpr : | test.swift:37:15:37:29 | CallExpr | From 507fdef028a620a5433e67eabde0ebb98e85a5d5 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 26 May 2022 17:33:12 +0000 Subject: [PATCH 07/11] Swift: add more data flow tests --- .../dataflow/dataflow/DataFlow.expected | 39 ++++++++++++------- .../dataflow/dataflow/LocalFlow.expected | 17 +++++++- .../dataflow/dataflow/test.swift | 28 ++++++++++++- 3 files changed, 66 insertions(+), 18 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index 164674b22a8..e3c07f8ce70 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -2,28 +2,39 @@ edges | test.swift:6:19:6:26 | CallExpr : | test.swift:7:15:7:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr : | test.swift:9:15:9:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr : | test.swift:10:15:10:15 | DeclRefExpr | -| test.swift:25:20:25:27 | CallExpr : | test.swift:28:18:28:21 | ParamDecl : | -| test.swift:25:20:25:27 | CallExpr : | test.swift:28:18:28:21 | WriteDef : | -| test.swift:28:18:28:21 | ParamDecl : | test.swift:29:15:29:15 | DeclRefExpr | -| test.swift:28:18:28:21 | WriteDef : | test.swift:29:15:29:15 | DeclRefExpr | -| test.swift:33:12:33:19 | CallExpr : | test.swift:37:15:37:29 | CallExpr | +| test.swift:25:20:25:27 | CallExpr : | test.swift:29:18:29:21 | ParamDecl : | +| test.swift:25:20:25:27 | CallExpr : | test.swift:29:18:29:21 | WriteDef : | +| test.swift:26:26:26:33 | CallExpr : | test.swift:29:26:29:29 | ParamDecl : | +| test.swift:26:26:26:33 | CallExpr : | test.swift:29:26:29:29 | WriteDef : | +| test.swift:29:18:29:21 | ParamDecl : | test.swift:30:15:30:15 | DeclRefExpr | +| test.swift:29:18:29:21 | WriteDef : | test.swift:30:15:30:15 | DeclRefExpr | +| test.swift:29:26:29:29 | ParamDecl : | test.swift:31:15:31:15 | DeclRefExpr | +| test.swift:29:26:29:29 | WriteDef : | test.swift:31:15:31:15 | DeclRefExpr | +| test.swift:35:12:35:19 | CallExpr : | test.swift:39:15:39:29 | CallExpr | nodes | test.swift:6:19:6:26 | CallExpr : | semmle.label | CallExpr : | | test.swift:7:15:7:15 | DeclRefExpr | semmle.label | DeclRefExpr | | test.swift:9:15:9:15 | DeclRefExpr | semmle.label | DeclRefExpr | | test.swift:10:15:10:15 | DeclRefExpr | semmle.label | DeclRefExpr | | test.swift:25:20:25:27 | CallExpr : | semmle.label | CallExpr : | -| test.swift:28:18:28:21 | ParamDecl : | semmle.label | ParamDecl : | -| test.swift:28:18:28:21 | ParamDecl : | semmle.label | WriteDef : | -| test.swift:28:18:28:21 | WriteDef : | semmle.label | ParamDecl : | -| test.swift:28:18:28:21 | WriteDef : | semmle.label | WriteDef : | -| test.swift:29:15:29:15 | DeclRefExpr | semmle.label | DeclRefExpr | -| test.swift:33:12:33:19 | CallExpr : | semmle.label | CallExpr : | -| test.swift:37:15:37:29 | CallExpr | semmle.label | CallExpr | +| test.swift:26:26:26:33 | CallExpr : | semmle.label | CallExpr : | +| test.swift:29:18:29:21 | ParamDecl : | semmle.label | ParamDecl : | +| test.swift:29:18:29:21 | ParamDecl : | semmle.label | WriteDef : | +| test.swift:29:18:29:21 | WriteDef : | semmle.label | ParamDecl : | +| test.swift:29:18:29:21 | WriteDef : | semmle.label | WriteDef : | +| test.swift:29:26:29:29 | ParamDecl : | semmle.label | ParamDecl : | +| test.swift:29:26:29:29 | ParamDecl : | semmle.label | WriteDef : | +| test.swift:29:26:29:29 | WriteDef : | semmle.label | ParamDecl : | +| test.swift:29:26:29:29 | WriteDef : | semmle.label | WriteDef : | +| test.swift:30:15:30:15 | DeclRefExpr | semmle.label | DeclRefExpr | +| test.swift:31:15:31:15 | DeclRefExpr | semmle.label | DeclRefExpr | +| test.swift:35:12:35:19 | CallExpr : | semmle.label | CallExpr : | +| test.swift:39:15:39:29 | CallExpr | semmle.label | CallExpr | subpaths #select | test.swift:6:19:6:26 | CallExpr : | test.swift:7:15:7:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr : | test.swift:9:15:9:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr : | test.swift:10:15:10:15 | DeclRefExpr | -| test.swift:25:20:25:27 | CallExpr : | test.swift:29:15:29:15 | DeclRefExpr | -| test.swift:33:12:33:19 | CallExpr : | test.swift:37:15:37:29 | CallExpr | +| test.swift:25:20:25:27 | CallExpr : | test.swift:30:15:30:15 | DeclRefExpr | +| test.swift:26:26:26:33 | CallExpr : | test.swift:31:15:31:15 | DeclRefExpr | +| test.swift:35:12:35:19 | CallExpr : | test.swift:39:15:39:29 | CallExpr | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 611ef065883..479031df4c5 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -1,5 +1,6 @@ | file://:0:0:0:0 | Phi | test.swift:15:15:15:15 | DeclRefExpr | | file://:0:0:0:0 | Phi | test.swift:21:15:21:15 | DeclRefExpr | +| file://:0:0:0:0 | Phi | test.swift:50:15:50:15 | DeclRefExpr | | test.swift:6:9:6:13 | WriteDef | test.swift:7:15:7:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr | test.swift:6:9:6:13 | WriteDef | | test.swift:7:15:7:15 | DeclRefExpr | test.swift:8:10:8:10 | DeclRefExpr | @@ -13,5 +14,17 @@ | test.swift:17:10:17:10 | IntegerLiteralExpr | test.swift:17:5:17:10 | WriteDef | | test.swift:19:14:19:14 | DeclRefExpr | test.swift:19:9:19:14 | WriteDef | | test.swift:19:14:19:14 | DeclRefExpr | test.swift:19:14:19:14 | DeclRefExpr | -| test.swift:28:18:28:21 | ParamDecl | test.swift:29:15:29:15 | DeclRefExpr | -| test.swift:28:18:28:21 | WriteDef | test.swift:29:15:29:15 | DeclRefExpr | +| test.swift:29:18:29:21 | ParamDecl | test.swift:30:15:30:15 | DeclRefExpr | +| test.swift:29:18:29:21 | WriteDef | test.swift:30:15:30:15 | DeclRefExpr | +| test.swift:29:26:29:29 | ParamDecl | test.swift:31:15:31:15 | DeclRefExpr | +| test.swift:29:26:29:29 | WriteDef | test.swift:31:15:31:15 | DeclRefExpr | +| test.swift:42:16:42:19 | ParamDecl | test.swift:45:8:45:8 | DeclRefExpr | +| test.swift:42:16:42:19 | WriteDef | test.swift:45:8:45:8 | DeclRefExpr | +| test.swift:43:9:43:13 | WriteDef | test.swift:46:13:46:13 | DeclRefExpr | +| test.swift:43:19:43:26 | CallExpr | test.swift:43:9:43:13 | WriteDef | +| test.swift:46:13:46:13 | DeclRefExpr | test.swift:46:9:46:13 | WriteDef | +| test.swift:48:13:48:13 | IntegerLiteralExpr | test.swift:48:9:48:13 | WriteDef | +| test.swift:58:9:58:12 | WriteDef | test.swift:59:15:59:15 | DeclRefExpr | +| test.swift:58:18:58:18 | IntegerLiteralExpr | test.swift:58:9:58:12 | WriteDef | +| test.swift:59:15:59:15 | DeclRefExpr | test.swift:60:23:60:23 | DeclRefExpr | +| test.swift:60:23:60:23 | DeclRefExpr | test.swift:61:15:61:15 | DeclRefExpr | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index ae1135fb5d4..113db2dfea7 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -22,11 +22,13 @@ func intraprocedural_with_local_flow() -> Void { } func caller_source() -> Void { - callee_sink(x: source()) + callee_sink(x: source(), y: 1) + callee_sink(x: 1, y: source()) } -func callee_sink(x: Int) -> Void { +func callee_sink(x: Int, y: Int) -> Void { sink(arg: x) + sink(arg: y) } func callee_source() -> Int { @@ -36,3 +38,25 @@ func callee_source() -> Int { func caller_sink() -> Void { sink(arg: callee_source()) } + +func branching(b: Bool) -> Void { + var t1: Int = source() + var t: Int = 0 + if(b) { + t = t1; + } else { + t = 1; + } + sink(arg: t) +} + +func inoutSource(arg: inout Int) -> Void { + arg = source() +} + +func inoutUser() { + var x: Int = 0 + sink(arg: x) + inoutSource(arg: &x) + sink(arg: x) +} \ No newline at end of file From 32e4c496f6d5e84a0690a912b017762002403b3e Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 26 May 2022 17:55:25 +0000 Subject: [PATCH 08/11] Swift: Dataflow through Phi nodes --- swift/ql/lib/codeql/swift/dataflow/Ssa.qll | 18 ++++++++++++++++++ .../dataflow/internal/DataFlowPrivate.qll | 11 +++++++++++ .../dataflow/dataflow/DataFlow.expected | 4 ++++ .../dataflow/dataflow/LocalFlow.expected | 11 ++++++++--- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll index b7a84caca28..b56e33d869f 100644 --- a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll +++ b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll @@ -72,4 +72,22 @@ module Ssa { ) } } + + cached class PhiDefinition extends Definition, SsaImplCommon::PhiNode { + cached + override Location getLocation() { + exists(BasicBlock bb, int i | + this.definesAt(_, bb, i) and + result = bb.getLocation() + ) + } + + cached Definition getPhiInput(BasicBlock bb) { + SsaImplCommon::phiHasInputFromBlock(this, result, bb) + } + + cached Definition getAPhiInput() { + result = this.getPhiInput(_) + } + } } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index e0853d28e28..1fc8bb36812 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -4,6 +4,7 @@ private import DataFlowDispatch private import codeql.swift.controlflow.CfgNodes private import codeql.swift.dataflow.Ssa private import codeql.swift.controlflow.BasicBlocks +private import codeql.swift.dataflow.internal.SsaImplCommon as SsaImpl /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallable() } @@ -46,6 +47,13 @@ private class SsaDefinitionNodeImpl extends SsaDefinitionNode, NodeImpl { } } +private predicate localFlowSsaInput(Node nodeFrom, Ssa::Definition def, Ssa::Definition next) { + exists(BasicBlock bb, int i | SsaImpl::lastRefRedef(def, bb, i, next) | + def.definesAt(_, bb, i) and + def = nodeFrom.asDefinition() + ) +} + /** A collection of cached types and predicates to be evaluated in the same stage. */ cached private module Cached { @@ -66,6 +74,9 @@ private module Cached { or // use-use flow def.adjacentReadPair(nodeFrom.getCfgNode(), nodeTo.getCfgNode()) + // step from previous read to Phi node + or + localFlowSsaInput(nodeFrom, def, nodeTo.asDefinition()) ) } diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index e3c07f8ce70..cd380247433 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -11,6 +11,7 @@ edges | test.swift:29:26:29:29 | ParamDecl : | test.swift:31:15:31:15 | DeclRefExpr | | test.swift:29:26:29:29 | WriteDef : | test.swift:31:15:31:15 | DeclRefExpr | | test.swift:35:12:35:19 | CallExpr : | test.swift:39:15:39:29 | CallExpr | +| test.swift:43:19:43:26 | CallExpr : | test.swift:50:15:50:15 | DeclRefExpr | nodes | test.swift:6:19:6:26 | CallExpr : | semmle.label | CallExpr : | | test.swift:7:15:7:15 | DeclRefExpr | semmle.label | DeclRefExpr | @@ -30,6 +31,8 @@ nodes | test.swift:31:15:31:15 | DeclRefExpr | semmle.label | DeclRefExpr | | test.swift:35:12:35:19 | CallExpr : | semmle.label | CallExpr : | | test.swift:39:15:39:29 | CallExpr | semmle.label | CallExpr | +| test.swift:43:19:43:26 | CallExpr : | semmle.label | CallExpr : | +| test.swift:50:15:50:15 | DeclRefExpr | semmle.label | DeclRefExpr | subpaths #select | test.swift:6:19:6:26 | CallExpr : | test.swift:7:15:7:15 | DeclRefExpr | @@ -38,3 +41,4 @@ subpaths | test.swift:25:20:25:27 | CallExpr : | test.swift:30:15:30:15 | DeclRefExpr | | test.swift:26:26:26:33 | CallExpr : | test.swift:31:15:31:15 | DeclRefExpr | | test.swift:35:12:35:19 | CallExpr : | test.swift:39:15:39:29 | CallExpr | +| test.swift:43:19:43:26 | CallExpr : | test.swift:50:15:50:15 | DeclRefExpr | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 479031df4c5..7fb2a6ce9e9 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -1,6 +1,3 @@ -| file://:0:0:0:0 | Phi | test.swift:15:15:15:15 | DeclRefExpr | -| file://:0:0:0:0 | Phi | test.swift:21:15:21:15 | DeclRefExpr | -| file://:0:0:0:0 | Phi | test.swift:50:15:50:15 | DeclRefExpr | | test.swift:6:9:6:13 | WriteDef | test.swift:7:15:7:15 | DeclRefExpr | | test.swift:6:19:6:26 | CallExpr | test.swift:6:9:6:13 | WriteDef | | test.swift:7:15:7:15 | DeclRefExpr | test.swift:8:10:8:10 | DeclRefExpr | @@ -10,8 +7,13 @@ | test.swift:9:15:9:15 | DeclRefExpr | test.swift:11:8:11:8 | DeclRefExpr | | test.swift:12:9:12:14 | WriteDef | test.swift:13:19:13:19 | DeclRefExpr | | test.swift:12:14:12:14 | IntegerLiteralExpr | test.swift:12:9:12:14 | WriteDef | +| test.swift:15:5:15:5 | Phi | test.swift:15:15:15:15 | DeclRefExpr | | test.swift:15:15:15:15 | DeclRefExpr | test.swift:19:14:19:14 | DeclRefExpr | +| test.swift:17:5:17:10 | WriteDef | test.swift:18:11:18:11 | Phi | | test.swift:17:10:17:10 | IntegerLiteralExpr | test.swift:17:5:17:10 | WriteDef | +| test.swift:18:11:18:11 | Phi | test.swift:19:9:19:14 | WriteDef | +| test.swift:18:11:18:11 | Phi | test.swift:21:15:21:15 | DeclRefExpr | +| test.swift:19:9:19:14 | WriteDef | test.swift:18:11:18:11 | Phi | | test.swift:19:14:19:14 | DeclRefExpr | test.swift:19:9:19:14 | WriteDef | | test.swift:19:14:19:14 | DeclRefExpr | test.swift:19:14:19:14 | DeclRefExpr | | test.swift:29:18:29:21 | ParamDecl | test.swift:30:15:30:15 | DeclRefExpr | @@ -22,8 +24,11 @@ | test.swift:42:16:42:19 | WriteDef | test.swift:45:8:45:8 | DeclRefExpr | | test.swift:43:9:43:13 | WriteDef | test.swift:46:13:46:13 | DeclRefExpr | | test.swift:43:19:43:26 | CallExpr | test.swift:43:9:43:13 | WriteDef | +| test.swift:46:9:46:13 | WriteDef | test.swift:50:5:50:5 | Phi | | test.swift:46:13:46:13 | DeclRefExpr | test.swift:46:9:46:13 | WriteDef | +| test.swift:48:9:48:13 | WriteDef | test.swift:50:5:50:5 | Phi | | test.swift:48:13:48:13 | IntegerLiteralExpr | test.swift:48:9:48:13 | WriteDef | +| test.swift:50:5:50:5 | Phi | test.swift:50:15:50:15 | DeclRefExpr | | test.swift:58:9:58:12 | WriteDef | test.swift:59:15:59:15 | DeclRefExpr | | test.swift:58:18:58:18 | IntegerLiteralExpr | test.swift:58:9:58:12 | WriteDef | | test.swift:59:15:59:15 | DeclRefExpr | test.swift:60:23:60:23 | DeclRefExpr | From 2106d487857b8a0e4607e0f4b440a77a0f57cefd Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 30 May 2022 12:51:29 +0100 Subject: [PATCH 09/11] Swift: Add 'Argument.getIndex()' and use it in 'DataFlowDispatch'. --- .../dataflow/internal/DataFlowDispatch.qll | 24 +++++++------------ .../codeql/swift/elements/expr/Argument.qll | 3 +++ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll index 889f85d7450..d416f16b583 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll @@ -44,9 +44,7 @@ class DataFlowCallable extends TDataFlowCallable { * inside library callables with a flow summary. */ class DataFlowCall extends ExprNode { - DataFlowCall() { - this.asExpr() instanceof CallExpr - } + DataFlowCall() { this.asExpr() instanceof CallExpr } /** Gets the enclosing callable. */ DataFlowCallable getEnclosingCallable() { none() } @@ -59,19 +57,20 @@ private module Cached { /** Gets a viable run-time target for the call `call`. */ cached - DataFlowCallable viableCallable(DataFlowCall call) { + DataFlowCallable viableCallable(DataFlowCall call) { result = TDataFlowFunc(call.asExpr().(CallExpr).getStaticTarget()) } cached newtype TArgumentPosition = TThisArgument() or - TPositionalArgument(int n) { n in [0 .. 100] } // we rely on default exprs generated in the caller for ordering. TODO: compute range properly. TODO: varargs? + // we rely on default exprs generated in the caller for ordering + TPositionalArgument(int n) { n = any(Argument arg).getIndex() } cached - newtype TParameterPosition = - TThisParameter() or - TPositionalParameter(int n) { n in [0 .. 100] } // TODO: compute range properly + newtype TParameterPosition = + TThisParameter() or + TPositionalParameter(int n) { n = any(Argument arg).getIndex() } } import Cached @@ -95,12 +94,9 @@ class ParameterPosition extends TParameterPosition { } class PositionalParameterPosition extends ParameterPosition, TPositionalParameter { - int getIndex() { - this = TPositionalParameter(result) - } + int getIndex() { this = TPositionalParameter(result) } } - /** An argument position. */ class ArgumentPosition extends TArgumentPosition { /** Gets a textual representation of this position. */ @@ -108,9 +104,7 @@ class ArgumentPosition extends TArgumentPosition { } class PositionalArgumentPosition extends ArgumentPosition, TPositionalArgument { - int getIndex() { - this = TPositionalArgument(result) - } + int getIndex() { this = TPositionalArgument(result) } } /** Holds if arguments at position `apos` match parameters at position `ppos`. */ diff --git a/swift/ql/lib/codeql/swift/elements/expr/Argument.qll b/swift/ql/lib/codeql/swift/elements/expr/Argument.qll index c2a25b877a4..88c11b14013 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/Argument.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/Argument.qll @@ -1,5 +1,8 @@ private import codeql.swift.generated.expr.Argument +private import codeql.swift.elements.expr.ApplyExpr class Argument extends ArgumentBase { override string toString() { result = this.getLabel() + ": " + this.getExpr().toString() } + + int getIndex() { any(ApplyExpr apply).getArgument(result) = this } } From 425d66e454309b6f918cd17d06e3c7fc4490281f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 30 May 2022 12:52:48 +0100 Subject: [PATCH 10/11] Update swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll --- swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 1fc8bb36812..6eb554f933c 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -74,8 +74,8 @@ private module Cached { or // use-use flow def.adjacentReadPair(nodeFrom.getCfgNode(), nodeTo.getCfgNode()) - // step from previous read to Phi node or + // step from previous read to Phi node localFlowSsaInput(nodeFrom, def, nodeTo.asDefinition()) ) } From ef31aec29eebe2cb16635a69eb009104322d1337 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 30 May 2022 12:54:36 +0100 Subject: [PATCH 11/11] Swift: Autoformat. --- swift/ql/lib/codeql/swift/dataflow/Ssa.qll | 13 ++++++------- .../swift/dataflow/internal/DataFlowPrivate.qll | 14 ++++---------- .../library-tests/dataflow/dataflow/DataFlow.ql | 3 +-- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll index b56e33d869f..0f67b0faa5a 100644 --- a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll +++ b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll @@ -73,7 +73,8 @@ module Ssa { } } - cached class PhiDefinition extends Definition, SsaImplCommon::PhiNode { + cached + class PhiDefinition extends Definition, SsaImplCommon::PhiNode { cached override Location getLocation() { exists(BasicBlock bb, int i | @@ -82,12 +83,10 @@ module Ssa { ) } - cached Definition getPhiInput(BasicBlock bb) { - SsaImplCommon::phiHasInputFromBlock(this, result, bb) - } + cached + Definition getPhiInput(BasicBlock bb) { SsaImplCommon::phiHasInputFromBlock(this, result, bb) } - cached Definition getAPhiInput() { - result = this.getPhiInput(_) - } + cached + Definition getAPhiInput() { result = this.getPhiInput(_) } } } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 6eb554f933c..3de5e0dfdf9 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -166,17 +166,11 @@ abstract class ReturnNode extends Node { abstract ReturnKind getKind(); } -private module ReturnNodes { +private module ReturnNodes { class ReturnReturnNode extends ReturnNode, ExprNode { - ReturnReturnNode() { - exists(ReturnStmt stmt | - stmt.getResult() = this.asExpr() - ) - } + ReturnReturnNode() { exists(ReturnStmt stmt | stmt.getResult() = this.asExpr()) } - override ReturnKind getKind() { - result instanceof NormalReturnKind - } + override ReturnKind getKind() { result instanceof NormalReturnKind } } } @@ -188,7 +182,7 @@ abstract class OutNode extends Node { abstract DataFlowCall getCall(ReturnKind kind); } -private module OutNodes { +private module OutNodes { class CallOutNode extends OutNode, DataFlowCall { override DataFlowCall getCall(ReturnKind kind) { result = this and kind instanceof NormalReturnKind diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql index 3144222a652..be4f604a4f7 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.ql @@ -20,6 +20,5 @@ class TestConfiguration extends DataFlow::Configuration { } from DataFlow::PathNode src, DataFlow::PathNode sink, TestConfiguration test -where - test.hasFlowPath(src, sink) +where test.hasFlowPath(src, sink) select src, sink