Skip to content

Commit 4af95da

Browse files
authored
Merge pull request #6 from hvitved/rust/mad-barriers
Rust: Make `barrierModel` work
2 parents e47ba6a + 6e4d8bb commit 4af95da

File tree

3 files changed

+55
-13
lines changed

3 files changed

+55
-13
lines changed

rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,12 +1160,19 @@ private module Cached {
11601160
/** Holds if `n` is a flow barrier of kind `kind`. */
11611161
cached
11621162
predicate barrierNode(Node n, string kind) {
1163-
exists(string model |
1164-
n.(FlowSummaryNode)
1165-
.getSummaryNode()
1166-
.(FlowSummaryImpl::Private::SourceOutputNode)
1167-
.isEntry(kind, model)
1168-
// getSourceElement().(FlowBarrier).isBarrier(_, kind, _, _)
1163+
exists(
1164+
FlowSummaryImpl::Public::BarrierElement b,
1165+
FlowSummaryImpl::Private::SummaryComponentStack stack
1166+
|
1167+
FlowSummaryImpl::Private::barrierSpec(b, stack, kind, _)
1168+
|
1169+
n = FlowSummaryImpl::StepsInput::getSourceNode(b, stack, false)
1170+
or
1171+
// For barriers like `Argument[0]` we want to target the pre-update node
1172+
n =
1173+
FlowSummaryImpl::StepsInput::getSourceNode(b, stack, true)
1174+
.(PostUpdateNode)
1175+
.getPreUpdateNode()
11691176
)
11701177
}
11711178

rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ module Input implements InputSig<Location, RustDataFlow> {
143143

144144
private import Make<Location, RustDataFlow, Input> as Impl
145145

146-
private module StepsInput implements Impl::Private::StepsInputSig {
146+
module StepsInput implements Impl::Private::StepsInputSig {
147147
DataFlowCall getACall(Public::SummarizedCallable sc) { result.asCall().getStaticTarget() = sc }
148148

149149
/** Gets the argument of `source` described by `sc`, if any. */
@@ -171,18 +171,27 @@ private module StepsInput implements Impl::Private::StepsInputSig {
171171
result.asCfgScope() = source.getEnclosingCfgScope()
172172
}
173173

174-
RustDataFlow::Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) {
174+
additional RustDataFlow::Node getSourceNode(
175+
Input::SourceBase source, Impl::Private::SummaryComponentStack s, boolean isArgPostUpdate
176+
) {
175177
s.head() = Impl::Private::SummaryComponent::return(_) and
176-
result.asExpr() = source.getCall()
178+
result.asExpr() = source.getCall() and
179+
isArgPostUpdate = false
177180
or
178181
exists(RustDataFlow::ArgumentPosition pos, Expr arg |
179182
s.head() = Impl::Private::SummaryComponent::parameter(pos) and
180183
arg = getSourceNodeArgument(source, s.tail().headOfSingleton()) and
181-
result.asParameter() = getCallable(arg).getParam(pos.getPosition())
184+
result.asParameter() = getCallable(arg).getParam(pos.getPosition()) and
185+
isArgPostUpdate = false
182186
)
183187
or
184188
result.(RustDataFlow::PostUpdateNode).getPreUpdateNode().asExpr() =
185-
getSourceNodeArgument(source, s.headOfSingleton())
189+
getSourceNodeArgument(source, s.headOfSingleton()) and
190+
isArgPostUpdate = true
191+
}
192+
193+
RustDataFlow::Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) {
194+
result = getSourceNode(source, s, _)
186195
}
187196

188197
RustDataFlow::Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) {

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,19 @@ module Make<
736736
)
737737
}
738738

739-
private predicate summarySpec(string spec) {
739+
private predicate isRelevantBarrier(
740+
BarrierElement e, string output, string kind, Provenance provenance, string model
741+
) {
742+
e.isBarrier(output, kind, provenance, model) and
743+
(
744+
provenance.isManual()
745+
or
746+
provenance.isGenerated() and
747+
not exists(Provenance p | p.isManual() and e.isBarrier(_, kind, p, _))
748+
)
749+
}
750+
751+
private predicate flowSpec(string spec) {
740752
exists(SummarizedCallable c |
741753
c.propagatesFlow(spec, _, _, _, _, _)
742754
or
@@ -745,10 +757,12 @@ module Make<
745757
or
746758
isRelevantSource(_, spec, _, _, _)
747759
or
760+
isRelevantBarrier(_, spec, _, _, _)
761+
or
748762
isRelevantSink(_, spec, _, _, _)
749763
}
750764

751-
import AccessPathSyntax::AccessPath<summarySpec/1>
765+
import AccessPathSyntax::AccessPath<flowSpec/1>
752766

753767
/** Holds if specification component `token` parses as parameter `pos`. */
754768
predicate parseParam(AccessPathToken token, ArgumentPosition pos) {
@@ -1528,6 +1542,18 @@ module Make<
15281542
)
15291543
}
15301544

1545+
/**
1546+
* Holds if `barrier` is a relevant barrier element with output specification `outSpec`.
1547+
*/
1548+
predicate barrierSpec(
1549+
BarrierElement barrier, SummaryComponentStack outSpec, string kind, string model
1550+
) {
1551+
exists(string output |
1552+
isRelevantBarrier(barrier, output, kind, _, model) and
1553+
External::interpretSpec(output, outSpec)
1554+
)
1555+
}
1556+
15311557
signature module TypesInputSig {
15321558
/** Gets the type of content `c`. */
15331559
DataFlowType getContentType(ContentSet c);

0 commit comments

Comments
 (0)