mirror of
https://github.com/github/codeql.git
synced 2026-05-01 11:45:14 +02:00
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.
This commit is contained in:
@@ -399,5 +399,5 @@
|
||||
| ViableCallable.cs:422:13:422:37 | call to method Mock | ViableCallable.Mock<A4>() |
|
||||
| ViableCallable.cs:424:9:424:21 | call to method M | C15.A4.M<T1>() |
|
||||
| ViableCallable.cs:424:9:424:21 | call to method M | C15.A5.M<T1>() |
|
||||
| ViableCallable.cs:439:16:439:26 | call to method M1 | C16<String,Int32>.M1(string) |
|
||||
| ViableCallable.cs:439:9:439:19 | call to method M1 | C16<String,Int32>.M1(string) |
|
||||
| ViableCallable.cs:442:9:442:24 | call to method M2 | C16<String,Int32>.M2<T>(Func<T>) |
|
||||
|
||||
Reference in New Issue
Block a user