Skip to content

Commit

Permalink
Merge pull request #15507 from asgerf/shared/outbarrier-bugfix
Browse files Browse the repository at this point in the history
Shared: fix a bug in stateful outbarriers
  • Loading branch information
asgerf authored Feb 12, 2024
2 parents cbb9a64 + ee8e9a4 commit faefa05
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 20 deletions.
11 changes: 11 additions & 0 deletions java/ql/test/library-tests/dataflow/inoutbarriers/A.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
class A {
static String fsrc = "";
String fsink = "";

String src(String s) { return s; }

void sink(String s) { }

static String flowThroughSink(String s) {
A obj = new A();
obj.fsink = s;
return obj.fsink;
}

void foo() {
String s = fsrc;
sink(fsrc);
Expand All @@ -13,5 +20,9 @@ void foo() {
sink(s);

sink(s);

s = fsrc;
s = flowThroughSink(s);
sink(s);
}
}
12 changes: 7 additions & 5 deletions java/ql/test/library-tests/dataflow/inoutbarriers/test.expected
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
inconsistentFlow
#select
| A.java:9:16:9:19 | fsrc | A.java:13:10:13:10 | s | nobarrier, sinkbarrier |
| A.java:9:16:9:19 | fsrc | A.java:15:10:15:10 | s | nobarrier |
| A.java:10:10:10:13 | fsrc | A.java:10:10:10:13 | fsrc | both, nobarrier, sinkbarrier, srcbarrier |
| A.java:12:9:12:14 | src(...) | A.java:13:10:13:10 | s | both, nobarrier, sinkbarrier, srcbarrier |
| A.java:12:9:12:14 | src(...) | A.java:15:10:15:10 | s | nobarrier, srcbarrier |
| A.java:16:16:16:19 | fsrc | A.java:20:10:20:10 | s | nobarrier, sinkbarrier |
| A.java:16:16:16:19 | fsrc | A.java:22:10:22:10 | s | nobarrier |
| A.java:17:10:17:13 | fsrc | A.java:17:10:17:13 | fsrc | both, nobarrier, sinkbarrier, srcbarrier |
| A.java:19:9:19:14 | src(...) | A.java:20:10:20:10 | s | both, nobarrier, sinkbarrier, srcbarrier |
| A.java:19:9:19:14 | src(...) | A.java:22:10:22:10 | s | nobarrier, srcbarrier |
| A.java:24:9:24:12 | fsrc | A.java:11:17:11:17 | s | both, nobarrier, sinkbarrier, srcbarrier |
| A.java:24:9:24:12 | fsrc | A.java:26:10:26:10 | s | nobarrier, srcbarrier |
5 changes: 5 additions & 0 deletions java/ql/test/library-tests/dataflow/inoutbarriers/test.ql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ predicate sink0(Node n) {
sink.getMethod().hasName("sink") and
sink.getAnArgument() = n.asExpr()
)
or
exists(AssignExpr assign |
assign.getDest().(FieldAccess).getField().hasName("fsink") and
n.asExpr() = assign.getSource()
)
}

module Conf1 implements ConfigSig {
Expand Down
33 changes: 18 additions & 15 deletions shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -2682,6 +2682,7 @@ module MakeImpl<InputSig Lang> {
) {
not isUnreachableInCall1(node2, cc) and
not inBarrier(node2, state) and
not outBarrier(node1, state) and
(
localFlowEntry(node1, pragma[only_bind_into](state)) and
(
Expand Down Expand Up @@ -3761,6 +3762,9 @@ module MakeImpl<InputSig Lang> {

override NodeEx getNodeEx() { result = node }

pragma[inline]
final NodeEx getNodeExOutgoing() { result = node and not outBarrier(node, state) }

override FlowState getState() { result = state }

CallContext getCallContext() { result = cc }
Expand All @@ -3777,14 +3781,11 @@ module MakeImpl<InputSig Lang> {
}

override PathNodeImpl getASuccessorImpl() {
not outBarrier(node, state) and
(
// an intermediate step to another intermediate node
result = this.getSuccMid()
or
// a final step to a sink
result = this.getSuccMid().projectToSink()
)
// an intermediate step to another intermediate node
result = this.getSuccMid()
or
// a final step to a sink
result = this.getSuccMid().projectToSink()
}

override predicate isSource() {
Expand Down Expand Up @@ -3935,22 +3936,22 @@ module MakeImpl<InputSig Lang> {
ap instanceof AccessPathNil
)
or
jumpStepEx(mid.getNodeEx(), node) and
jumpStepEx(mid.getNodeExOutgoing(), node) and
state = mid.getState() and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
t = mid.getType() and
ap = mid.getAp()
or
additionalJumpStep(mid.getNodeEx(), node) and
additionalJumpStep(mid.getNodeExOutgoing(), node) and
state = mid.getState() and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
t = node.getDataFlowType() and
ap = TAccessPathNil()
or
additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state) and
additionalJumpStateStep(mid.getNodeExOutgoing(), mid.getState(), node, state) and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
Expand Down Expand Up @@ -3985,7 +3986,7 @@ module MakeImpl<InputSig Lang> {
) {
ap0 = mid.getAp() and
c = ap0.getHead() and
Stage5::readStepCand(mid.getNodeEx(), c, node) and
Stage5::readStepCand(mid.getNodeExOutgoing(), c, node) and
state = mid.getState() and
cc = mid.getCallContext()
}
Expand All @@ -3998,7 +3999,7 @@ module MakeImpl<InputSig Lang> {
exists(DataFlowType contentType |
t0 = mid.getType() and
ap0 = mid.getAp() and
Stage5::storeStepCand(mid.getNodeEx(), _, c, node, contentType, t) and
Stage5::storeStepCand(mid.getNodeExOutgoing(), _, c, node, contentType, t) and
state = mid.getState() and
cc = mid.getCallContext() and
compatibleTypes(t0, contentType)
Expand All @@ -4016,7 +4017,8 @@ module MakeImpl<InputSig Lang> {
not outBarrier(retNode, state) and
innercc = mid.getCallContext() and
innercc instanceof CallContextNoCall and
apa = mid.getAp().getApprox()
apa = mid.getAp().getApprox() and
not outBarrier(retNode, state)
)
}

Expand Down Expand Up @@ -4137,7 +4139,8 @@ module MakeImpl<InputSig Lang> {
pathNode(_, ret, state, cc, sc, t, ap, _) and
kind = ret.getKind() and
apa = ap.getApprox() and
parameterFlowThroughAllowed(sc.getParamNode(), kind)
parameterFlowThroughAllowed(sc.getParamNode(), kind) and
not outBarrier(ret, state)
)
}

Expand Down

0 comments on commit faefa05

Please sign in to comment.