Data flow: Add section on lambda flow to `dataflow.md`

This commit is contained in:
Tom Hvitved 2021-03-19 13:54:03 +01:00
Родитель 09a49e4580
Коммит 18ac2596d0
1 изменённых файлов: 39 добавлений и 0 удалений

Просмотреть файл

@ -186,6 +186,45 @@ values, for example through `out` parameters in C#, the `ReturnKind` class can
be defined and used to match up different kinds of `ReturnNode`s with the
corresponding `OutNode`s.
#### Lambda flow
For lambda-like calls, the library supports built-in call resolution based on data flow between a lambda creation expression and a lambda call. The interface that needs to be implemented is
```ql
class LambdaCallKind
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver)
/** Extra data-flow steps needed for lamba flow analysis. */
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue)
```
with the semantics that `call` will resolve to `c` if there is a data-flow path from `creation` to `receiver`, with matching `kind`s.
The implementation keeps track of a one-level call context, which means that we are able to handle situations like this:
```csharp
Apply(f, x) { f(x); }
Apply(x => NonSink(x), "tainted"); // GOOD
Apply(x => Sink(x), "not tainted"); // GOOD
```
However, since we only track one level the following example will have false-positive flow:
```csharp
Apply(f, x) { f(x); }
ApplyWrapper(f, x) { Apply(f, x) }
ApplyWrapper(x => NonSink(x), "tainted"); // GOOD (FALSE POSITIVE)
ApplyWrapper(x => Sink(x), "not tainted"); // GOOD (FALSE POSITIVE)
```
## Flow through global variables
Flow through global variables are called jump-steps, since such flow steps