Commit Graph

194 Commits

Author SHA1 Message Date
Tom Hvitved
d1755500e4 C#: Data flow through fields
Initial implementation of data flow through fields, using the algorithm of the
shared data flow implementation. Fields (and field-like properties) are covered,
and stores can be either
 - ordinary assignments, `Foo = x`,
 - object initializers, `new C() { Foo = x }`, or
 - field initializers, `int Foo = x`.

For field initializers, we need to synthesize calls (`SynthesizedCall`),
callables (`SynthesizedCallable`), parameters (`InstanceParameterNode`), and
arguments (`SynthesizedThisArgumentNode`), as the C# extractor does not (yet)
extract such entities. For example, in

```
class C
{
    int Field1 = 1;
    int Field2 = 2;

    C() { }
}
```

there is a synthesized call from the constructor `C`, with a synthesized `this`
argument, and the targets of that call are two synthesized callables with bodies
`this.Field1 = 1` and `this.Field2 = 2`, respectively.

A consequence of this is that `DataFlowCallable` is no longer an alias for
`DotNet::Callable`, but instead an IPA type.
2019-08-16 15:49:37 +02:00
Tom Hvitved
5ecf680cc2 C#: Improve performance of SSA adjacent reads calculation
- Speedup the `varBlockReaches()` predicate, by restricting to basic blocks
  in which a given SSA definition may still be live, in constrast to just
  being able to reach *any* access (read or write) to the underlying source
  variable.
- Account for some missing cases in the `lastRead()` predicate.
2019-08-08 16:21:57 +02:00
Tom Hvitved
4d58154ff5 C#: Fix data flow for out/ref parameters 2019-08-02 14:25:38 -07:00
Tom Hvitved
04db1bf3f4 C#: Add data flow test for methods with multiple out/ref parameters 2019-08-02 13:46:18 -07:00
semmle-qlci
f58c7cc79c Merge pull request #1446 from hvitved/csharp/cached-stages
Approved by calumgrant
2019-06-27 08:03:24 +01:00
Tom Hvitved
a1d7382a67 C#: Update expected test output 2019-06-17 20:07:54 +02:00
Tom Hvitved
946be967f8 C#: Break up a big cached stage into multiple stages
- Add `Caching.qll` for controlling caching across multiple files.
- Move `isUncertainRefCall()` out of cached module in `Assignable.qll` to avoid
  collapsing with CFG stage.
- Remove dependency on `AlwaysNullExpr` in `NullValue::getAnExpr()` to avoid
  collapsing with CFG stage.
- Avoid caching pre-SSA library as it should only be used during the CFG construction
  stage.
2019-06-12 16:05:45 +02:00
Tom Hvitved
8c1cab2d03 C#: Simplify extraction of is expressions and case statements 2019-06-03 15:50:41 +02:00
Tom Hvitved
e1d4166e3c C#: Data flow through this parameter 2019-05-20 13:42:32 +02:00
Tom Hvitved
c6a471e4b6 C#: Adopt shared data flow implementation
- General refactoring to fit with the shared data flow implementation.
- Move CFG splitting logic into `ControlFlowReachability.qll`.
- Replace `isAdditionalFlowStepIntoCall()` with `TaintedParameterNode`.
- Redefine `ReturnNode` to be the actual values that are returned, which should
  yield better path information.
- No longer consider overrides in CIL calls.
2019-05-06 14:54:11 +02:00
Tom Hvitved
26debb846c C#: Change ImplicitCapturedArgumentNode::toString() 2019-05-06 14:54:11 +02:00
Tom Hvitved
dfdfae8dd6 C#: Add more data flow tests 2019-05-03 09:41:39 +02:00
Tom Hvitved
b48576d7b9 C#: Address review comments 2019-03-10 15:45:31 +01:00
Tom Hvitved
e6f7632d4c C#: Introduce data flow return nodes
Before this change,

```
flowOutOfCallableStep(CallNode call, ReturnNode ret, OutNode out, CallContext cc)
```

would compute all combinations of call sites `call` and returned expressions `ret`
up front.

Now, we instead introduce explicit return nodes, so each callable has exactly
one return node (as well as one for each `out`/`ref` parameter). There is then
local flow from a returned expression to the relevant return node, and
`flowOutOfCallableStep()` computes combinations of call sites and return nodes.

Not only does this result in better performance, it also makes `flowOutOfCallableStep()`
symmetric to `flowIntoCallableStep()`, where each argument is mapped to a parameter,
and not to all reads of that parameter.
2019-03-07 12:16:06 +01:00
Tom Hvitved
5ce9b25ec9 C#: Improve CFG for assignments
Write accesses in assignments, such as the access to `x` in `x = 0` are not
evaluated, so they should not have entries in the control flow graph. However,
qualifiers (and indexer arguments) should still be evaluated, for example in

```
x.Foo.Bar = 0;
```

the CFG should be `x --> x.Foo --> 0 --> x.Foo.Bar = 0` (as opposed to
`x --> x.Foo --> x.Foo.Bar --> 0 --> x.Foo.Bar = 0`, prior to this change).

A special case is assignments via acessors (properties, indexers, and event
adders), where we do want to include the access in the control flow graph,
as it represents the accessor call:

```
x.Prop = 0;
```

But instead of `x --> x.set_Prop --> 0 --> x.Prop = 0` the CFG should be
`x --> 0 --> x.set_Prop --> x.Prop = 0`, as the setter is called *after* the
assigned value has been evaluated.

An even more special case is tuple assignments via accessors:

```
(x.Prop1, y.Prop2) = (0, 1);
```

Here the CFG should be
`x --> y --> 0 --> 1 --> x.set_Prop1 --> y.set_Prop2 --> (x.Prop1, y.Prop2) = (0, 1)`.
2019-02-16 19:19:24 +01:00
Tom Hvitved
8cb8c967d2 C#: Remove some impossible CFG exception edges 2019-02-11 16:17:01 +01:00
Tom Hvitved
3503e9b57e C#: Move PreSsa module into own file 2019-02-05 14:27:09 +01:00
Tom Hvitved
d829d98165 Merge branch 'master' into csharp/autoformat 2019-02-05 10:37:42 +01:00
Tom Hvitved
b4b6fdd12b C#: Revert recent change to AccessorCall
The recent change to `AccessorCall` on dd99525566 resulted
in some bad join-orders, so I have (partly) reverted them. This means that the issues
orignally addressed by that change are now reintroduced, and I plan to instead apply a
fix to the CFG, which--unlike the original fix--should be able to handle multi-property-tuple
assignments.
2019-02-04 15:14:18 +01:00
Tom Hvitved
910995af90 C#: Autoformat QL code 2019-02-04 10:32:30 +01:00
Calum Grant
eef1abfa69 Merge pull request #743 from hvitved/csharp/dataflow-splitting
C#: Teach data flow library about CFG splitting
2019-01-28 16:31:24 +00:00
Tom Hvitved
dd99525566 C#: Redefine AccessorCall
The syntactic node assiociated with accessor calls was previously always the
underlying member access. For example, in

```
x.Prop = y.Prop;
```

the implicit call to `x.set_Prop()` was at the syntactic node `x.Prop`, while the
implicit call to `y.get_Prop()` was at the syntactic node `y.Prop`.

However, this breaks the invariant that arguments to calls dominate the call itself,
as the argument `y.Prop` for the implicit `value` parameter in `x.set_Prop()` will
be evaluated after the call (the left-hand side in an assignment is evaluated before
the right-hand side).

The solution is to redefine the access call to `x.set_Prop()` to point to the whole
assignment `x.Prop = y.Prop`, instead of the access `x.Prop`. For reads, we still want
to associate the accessor call with the member access.

A corner case arises when multiple setters are called in a tuple assignment:

```
(x.Prop1, x.Prop2) = (0, 1)
```

In this case, we cannot associate the assignment with both `x.set_Prop1()` and
`x.set_Prop2()`, so we instead revert to using the underlying member accesses as
before.
2019-01-18 13:56:23 +01:00
Tom Hvitved
b2f99dbbc7 C#: Teach data flow library about CFG splitting
Data flow nodes for expressions do not take CFG splitting into account. Example:

```
if (b)
    x = tainted;
x = x.ToLower();
if (!b)
    Use(x);
```

Flow is incorrectly reported from `tainted` to `x` in `Use(x)`, because the step
from `tainted` to `x.ToLower()` throws away the information that `b = true`.

The solution is to remember the splitting in data flow expression nodes, that is,
to represent the exact control flow node instead of just the expression. With that
we get flow from `tainted` to `[b = true] x.ToLower()`, but not from `tainted` to
`[b = false] x.ToLower()`.

The data flow API remains unchanged, but in order for analyses to fully benefit from
CFG splitting, sanitizers in particular should be CFG-based instead of expression-based:

```
if (b)
   x = tainted;
   if (IsInvalid(x))
       return;
Use(x);
```

If the call to `IsInvalid()` is a sanitizer, then defining an expression node to be
a sanitizer using `GuardedExpr` will be too conservative (`x` in `Use(x)` is in fact
not guarded). However, `[b = true] x` in `[b = true] Use(x)` is guarded, and to help
defining guard-based sanitizers, the class `GuardedDataFlowNode` has been introduced.
2019-01-16 10:39:27 +01:00
Tom Hvitved
f768abb0e6 C#: Add data flow test with CFG splitting 2019-01-16 10:29:26 +01:00
Tom Hvitved
abb3f71ec8 C#: Add GuardedControlFlowNode 2019-01-16 10:29:26 +01:00
Calum Grant
d4d5c47adb Merge pull request #749 from hvitved/csharp/remove-def-use
C#: Remove `DefUse.qll`
2019-01-15 10:52:39 +00:00
Tom Hvitved
390ebc96ae C#: Autoformat QL files 2019-01-11 13:55:28 +01:00
Tom Hvitved
c06fc2af09 C#: Remove DefUse.qll 2019-01-11 09:35:38 +01:00
Tom Hvitved
5879e58741 C#: Account for CFG splitting in AssignableDefinition::getAFirstRead() and AssignableRead::getANextRead() 2019-01-02 09:50:13 +01:00
Tom Hvitved
f06a20f666 C#: Add SSA tests with CFG splitting 2019-01-02 09:48:04 +01:00
Tom Hvitved
231465143d C#: Autoformat QL tests 2018-12-20 10:19:59 +01:00
Tom Hvitved
edf1df1577 C#: Remove tests for deprecated predicates 2018-12-18 10:43:12 +01:00
Tom Hvitved
ab7a094439 C#: Include CFG splits in Ssa::Definition::toString()
Just like syntax elements can be split in the control flow graph, so can SSA
definitions. To make this clear, and to make debugging easier, this commit
adds the splits as a prefix in the textual representation of SSA definitions.
2018-11-29 10:00:08 +01:00
Tom Hvitved
201f64ef8e Merge pull request #367 from calumgrant/cs/path-problems
C#: Update all security queries to path-problems
2018-11-22 12:02:11 +01:00
calum
3eae1cd500 C#: Update test outputs. 2018-11-21 17:28:48 +00:00
Tom Hvitved
3e78c2671f C#: Generalize pre-SSA library to include local-scope-like fields/properties 2018-11-20 15:07:44 +01:00
Tom Hvitved
25150265dc C#: Compute phi inputs in pre-SSA library
Logic is copied directly from the ordinary SSA library.
2018-11-20 15:07:43 +01:00
Tom Hvitved
98db3f89c2 C#: Extend pre-SSA consistency tests 2018-10-11 13:59:06 +02:00
Tom Hvitved
a48d77f7b8 C#: Add internal PreSsa library 2018-09-28 14:59:38 +02:00
Tom Hvitved
42faabc552 C#: Rename and restructure control flow graph entities
Follow a naming structure similar to the data flow library:

- `ControlFlowNode` -> `ControlFlow::Node`.
- `CallableEntryNode` -> `ControlFlow::Nodes::EntryNode`.
- `CallableExitNode` -> `ControlFlow::Nodes::ExitNode`.
- `ControlFlowEdgeType` -> `ControlFlow::SuccessorType`.
- `ControlFlowEdgeSuccessor` -> `ControlFlow::SuccessorTypes::NormalSuccessor`.
- `ControlFlowEdgeConditional -> ControlFlow::SuccessorTypes::ConditionalSuccessor`.
- `ControlFlowEdgeBoolean` -> `ControlFlow::SuccessorTypes::BooleanSuccessor`.
- `ControlFlowEdgeNullness` -> `ControlFlow::SuccessorTypes::NullnessSuccessor`.
- `ControlFlowEdgeMatching` -> `ControlFlow::SuccessorTypes::MatchingSuccessor`.
- `ControlFlowEdgeEmptiness` -> `ControlFlow::SuccessorTypes::EmptinessSuccessor`.
- `ControlFlowEdgeReturn` -> `ControlFlow::SuccessorTypes::ReturnSuccessor`.
- `ControlFlowEdgeBreak` -> `ControlFlow::SuccessorTypes::BreakSuccessor`.
- `ControlFlowEdgeContinue` -> `ControlFlow::SuccessorTypes::ContinueSuccessor`.
- `ControlFlowEdgeGotoLabel` -> `ControlFlow::SuccessorTypes::GotoLabelSuccessor`.
- `ControlFlowEdgeGotoCase` -> `ControlFlow::SuccessorTypes::GotoCaseSuccessor`.
- `ControlFlowEdgeGotoDefault` -> `ControlFlow::SuccessorTypes::GotoDefaultSuccessor`.
- `ControlFlowEdgeException` -> `ControlFlow::SuccessorTypes::ExceptionSuccessor`
2018-09-05 14:20:26 +02:00
Tom Hvitved
124a00ba10 C#: Update expected output in SSA tests 2018-09-04 20:15:33 +02:00
Tom Hvitved
9a7746e9b5 C#: Fix bug in BaseSsa library 2018-09-04 15:16:20 +02:00
Tom Hvitved
81122ca7a4 C#: Add test that reveals bug in BaseSsa implementation 2018-09-04 13:58:59 +02:00
Pavel Avgustinov
b55526aa58 QL code and tests for C#/C++/JavaScript. 2018-08-02 17:53:23 +01:00