Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions change-notes/1.22/analysis-java.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
|----------------------------|------------------------|------------------------------------------------------------------|
| Equals method does not inspect argument type (`java/unchecked-cast-in-equals`) | Fewer false positive and more true positive results | Precision has been improved by doing a bit of inter-procedural analysis and relying less on ad-hoc method names. |
| Uncontrolled data in arithmetic expression (`java/uncontrolled-arithmetic`) | Fewer false positive results | Precision has been improved in several ways, in particular, by better detection of guards along the data-flow path. |
| Uncontrolled data used in path expression (`java/path-injection`) | Fewer false positive results | The query no longer reports results guarded by `!var.contains("..")`. |
| User-controlled data in arithmetic expression (`java/tainted-arithmetic`) | Fewer false positive results | Precision has been improved in several ways, in particular, by better detection of guards along the data-flow path. |

## Changes to QL libraries
Expand Down
8 changes: 8 additions & 0 deletions cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
19 changes: 19 additions & 0 deletions cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,22 @@ VariableAccess getAnAccessToAssignedVariable(Expr assign) {
result = var.getAnAccess()
)
}

/**
* A guard that validates some expression.
*
* To use this in a configuration, extend the class and provide a
* characteristic predicate precisely specifying the guard, and override
* `checks` to specify what is being validated and in which branch.
*
* It is important that all extending classes in scope are disjoint.
*/
class BarrierGuard extends Expr {
/** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `branch`. */
abstract deprecated predicate checks(Expr e, boolean branch);

/** Gets a node guarded by this guard. */
final Node getAGuardedNode() {
none() // stub
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
20 changes: 20 additions & 0 deletions cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

private import cpp
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.controlflow.IRGuards

/**
* A node in a data flow graph.
Expand Down Expand Up @@ -166,3 +167,22 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) {
* (intra-procedural) steps.
*/
predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }

/**
* A guard that validates some expression.
*
* To use this in a configuration, extend the class and provide a
* characteristic predicate precisely specifying the guard, and override
* `checks` to specify what is being validated and in which branch.
*
* It is important that all extending classes in scope are disjoint.
*/
class BarrierGuard extends IRGuardCondition {
/** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `b`. */
abstract deprecated predicate checks(Instruction e, boolean b);

/** Gets a node guarded by this guard. */
final Node getAGuardedNode() {
none() // stub
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }

/** Holds if data flow through nodes guarded by `guard` is prohibited. */
predicate isBarrierGuard(BarrierGuard guard) { none() }

/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
Expand Down Expand Up @@ -136,6 +139,11 @@ private predicate fullBarrier(Node node, Configuration config) {
or
config.isBarrierOut(node) and
not config.isSink(node)
or
exists(BarrierGuard g |
config.isBarrierGuard(g) and
node = g.getAGuardedNode()
)
}

private class AdditionalFlowStepSource extends Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ private import cil
private import dotnet
private import DataFlowPrivate
private import semmle.code.csharp.Caching
private import semmle.code.csharp.controlflow.Guards

/**
* An element, viewed as a node in a data flow graph. Either an expression
Expand Down Expand Up @@ -162,3 +163,22 @@ abstract class NonLocalJumpNode extends Node {
/** Gets a successor node that is potentially in another callable. */
abstract Node getAJumpSuccessor(boolean preservesValue);
}

/**
* A guard that validates some expression.
*
* To use this in a configuration, extend the class and provide a
* characteristic predicate precisely specifying the guard, and override
* `checks` to specify what is being validated and in which branch.
*
* It is important that all extending classes in scope are disjoint.
*/
class BarrierGuard extends Internal::Guard {
/** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `v`. */
abstract deprecated predicate checks(Expr e, AbstractValue v);

/** Gets a node guarded by this guard. */
final Node getAGuardedNode() {
none() // stub
}
}
Loading