Skip to content

Commit 487606c

Browse files
committed
WIP barrier guards
1 parent 4f95fa7 commit 487606c

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

rust/ql/lib/codeql/rust/dataflow/FlowBarrier.qll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,27 @@ module FlowBarrier {
5151

5252
final class FlowBarrier = FlowBarrier::Range;
5353

54+
/** Provides the `Range` class used to define the extent of `FlowBarrierGuard`. */
55+
module FlowBarrierGuard {
56+
/** A flow barrier guard. */
57+
abstract class Range extends Impl::Public::BarrierGuardElement {
58+
bindingset[this]
59+
Range() { any() }
60+
61+
override predicate isBarrierGuard(
62+
string input, string branch, string kind, Impl::Public::Provenance provenance, string model
63+
) {
64+
this.isBarrierGuard(input, branch, kind) and provenance = "manual" and model = ""
65+
}
66+
67+
/**
68+
* Holds if this element is a flow barrier guard of kind `kind`, for data
69+
* flowing in as described by `input`, when `this` evaluates to `branch`.
70+
*/
71+
predicate isBarrierGuard(string input, string branch, string kind) { none() }
72+
}
73+
}
74+
75+
final class FlowBarrierGuard = FlowBarrierGuard::Range;
76+
5477
predicate barrierNode = DataFlowImpl::barrierNode/2;

shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,21 @@ module Make<
381381
abstract predicate isBarrier(string output, string kind, Provenance provenance, string model);
382382
}
383383

384+
/** A barrier guard element. */
385+
abstract class BarrierGuardElement extends SinkBaseFinal {
386+
bindingset[this]
387+
BarrierGuardElement() { any() }
388+
389+
/**
390+
* Holds if this element is a flow barrier guard of kind `kind`, for data
391+
* flowing in as described by `input`, when `this` evaluates to `branch`.
392+
*/
393+
pragma[nomagic]
394+
abstract predicate isBarrierGuard(
395+
string input, string branch, string kind, Provenance provenance, string model
396+
);
397+
}
398+
384399
private signature predicate hasKindSig(string kind);
385400

386401
signature class NeutralCallableSig extends SummarizedCallableBaseFinal {
@@ -748,6 +763,19 @@ module Make<
748763
)
749764
}
750765

766+
private predicate isRelevantBarrierGuard(
767+
BarrierGuardElement e, string input, string branch, string kind, Provenance provenance,
768+
string model
769+
) {
770+
e.isBarrierGuard(input, branch, kind, provenance, model) and
771+
(
772+
provenance.isManual()
773+
or
774+
provenance.isGenerated() and
775+
not exists(Provenance p | p.isManual() and e.isBarrierGuard(_, _, kind, p, _))
776+
)
777+
}
778+
751779
private predicate flowSpec(string spec) {
752780
exists(SummarizedCallable c |
753781
c.propagatesFlow(spec, _, _, _, _, _)
@@ -759,6 +787,8 @@ module Make<
759787
or
760788
isRelevantBarrier(_, spec, _, _, _)
761789
or
790+
isRelevantBarrierGuard(_, spec, _, _, _, _)
791+
or
762792
isRelevantSink(_, spec, _, _, _)
763793
}
764794

@@ -1554,6 +1584,19 @@ module Make<
15541584
)
15551585
}
15561586

1587+
/**
1588+
* Holds if `barrierGuard` is a relevant barrier guard element with input specification `inSpec`.
1589+
*/
1590+
predicate barrierSpec(
1591+
BarrierGuardElement barrierGuard, SummaryComponentStack inSpec, string branch, string kind,
1592+
string model
1593+
) {
1594+
exists(string input |
1595+
isRelevantBarrierGuard(barrierGuard, input, branch, kind, _, model) and
1596+
External::interpretSpec(input, inSpec)
1597+
)
1598+
}
1599+
15571600
signature module TypesInputSig {
15581601
/** Gets the type of content `c`. */
15591602
DataFlowType getContentType(ContentSet c);

0 commit comments

Comments
 (0)