mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
JS: Sanitize phi edges from barrier guards
This commit is contained in:
@@ -639,8 +639,16 @@ abstract class SsaPseudoDefinition extends SsaImplicitDefinition {
|
||||
* would be visible.
|
||||
*/
|
||||
class SsaPhiNode extends SsaPseudoDefinition, TPhi {
|
||||
/**
|
||||
* Gets the input to this phi node coming from the given predecessor block.
|
||||
*/
|
||||
SsaVariable getInputFromBlock(BasicBlock bb) {
|
||||
bb = getBasicBlock().getAPredecessor() and
|
||||
result = getDefReachingEndOf(bb, getSourceVariable())
|
||||
}
|
||||
|
||||
override SsaVariable getAnInput() {
|
||||
result = getDefReachingEndOf(getBasicBlock().getAPredecessor(), getSourceVariable())
|
||||
result = getInputFromBlock(_)
|
||||
}
|
||||
|
||||
override predicate definesAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
|
||||
|
||||
@@ -363,6 +363,51 @@ private predicate barrierGuardBlocksAccessPath(BarrierGuardNode guard, boolean o
|
||||
barrierGuardBlocksExpr(guard, outcome, ap.getAnInstance(), label)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `guard` should block flow along the edge `pred -> succ`.
|
||||
*
|
||||
* `label` is bound to the blocked label, or the empty string if all labels should be blocked.
|
||||
*/
|
||||
private predicate barrierGuardBlocksEdge(BarrierGuardNode guard, DataFlow::Node pred, DataFlow::Node succ, string label) {
|
||||
exists(SsaVariable input, SsaPhiNode phi, BasicBlock bb, ConditionGuardNode cond, boolean outcome |
|
||||
pred = DataFlow::ssaDefinitionNode(input) and
|
||||
succ = DataFlow::ssaDefinitionNode(phi) and
|
||||
input = phi.getInputFromBlock(bb) and
|
||||
guard.getEnclosingExpr() = cond.getTest() and
|
||||
outcome = cond.getOutcome() and
|
||||
barrierGuardBlocksExpr(guard, outcome, input.getAUse(), label) and
|
||||
cond.dominates(bb)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a barrier edge `pred -> succ` in `cfg` either through an explicit barrier edge
|
||||
* or one implied by a barrier guard.
|
||||
*
|
||||
* Only holds for barriers that should apply to all flow labels.
|
||||
*/
|
||||
private predicate isBarrierEdge(Configuration cfg, DataFlow::Node pred, DataFlow::Node succ) {
|
||||
cfg.isBarrierEdge(pred, succ)
|
||||
or
|
||||
exists(DataFlow::BarrierGuardNode guard |
|
||||
cfg.isBarrierGuard(guard) and
|
||||
barrierGuardBlocksEdge(guard, pred, succ, "")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a labeled barrier edge `pred -> succ` in `cfg` either through an explicit barrier edge
|
||||
* or one implied by a barrier guard.
|
||||
*/
|
||||
private predicate isLabeledBarrierEdge(Configuration cfg, DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel label) {
|
||||
cfg.isBarrierEdge(pred, succ, label)
|
||||
or
|
||||
exists(DataFlow::BarrierGuardNode guard |
|
||||
cfg.isBarrierGuard(guard) and
|
||||
barrierGuardBlocksEdge(guard, pred, succ, label)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A guard node that only blocks specific labels.
|
||||
*/
|
||||
@@ -470,7 +515,8 @@ private predicate basicFlowStep(
|
||||
// Local flow
|
||||
exists(FlowLabel predlbl, FlowLabel succlbl |
|
||||
localFlowStep(pred, succ, cfg, predlbl, succlbl) and
|
||||
not cfg.isBarrierEdge(pred, succ, predlbl) and
|
||||
not isLabeledBarrierEdge(cfg, pred, succ, predlbl) and
|
||||
not isBarrierEdge(cfg, pred, succ) and
|
||||
summary = MkPathSummary(false, false, predlbl, succlbl)
|
||||
)
|
||||
or
|
||||
@@ -584,7 +630,7 @@ private predicate callInputStep(
|
||||
)
|
||||
) and
|
||||
not cfg.isBarrier(succ) and
|
||||
not cfg.isBarrierEdge(pred, succ)
|
||||
not isBarrierEdge(cfg, pred, succ)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -638,7 +684,8 @@ private predicate flowThroughCall(
|
||||
ret.asExpr() = f.getAReturnedExpr() and
|
||||
calls(output, f) and // Do not consider partial calls
|
||||
reachableFromInput(f, output, input, ret, cfg, summary) and
|
||||
not cfg.isBarrierEdge(ret, output) and
|
||||
not isBarrierEdge(cfg, ret, output) and
|
||||
not isLabeledBarrierEdge(cfg, ret, output, summary.getEndLabel()) and
|
||||
not cfg.isLabeledBarrier(output, summary.getEndLabel())
|
||||
)
|
||||
or
|
||||
@@ -647,7 +694,8 @@ private predicate flowThroughCall(
|
||||
DataFlow::exceptionalInvocationReturnNode(output, invk.asExpr()) and
|
||||
calls(invk, f) and
|
||||
reachableFromInput(f, invk, input, ret, cfg, summary) and
|
||||
not cfg.isBarrierEdge(ret, output) and
|
||||
not isBarrierEdge(cfg, ret, output) and
|
||||
not isLabeledBarrierEdge(cfg, ret, output, summary.getEndLabel()) and
|
||||
not cfg.isLabeledBarrier(output, summary.getEndLabel())
|
||||
)
|
||||
}
|
||||
@@ -886,7 +934,8 @@ private predicate flowStep(
|
||||
flowIntoHigherOrderCall(pred, succ, cfg, summary)
|
||||
) and
|
||||
not cfg.isBarrier(succ) and
|
||||
not cfg.isBarrierEdge(pred, succ) and
|
||||
not isBarrierEdge(cfg, pred, succ) and
|
||||
not isLabeledBarrierEdge(cfg, pred, succ, summary.getEndLabel()) and
|
||||
not cfg.isLabeledBarrier(succ, summary.getEndLabel())
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,6 @@ typeInferenceMismatch
|
||||
| sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:26:9:26:14 | this.x |
|
||||
| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:45:8:45:8 | x |
|
||||
| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:48:10:48:10 | x |
|
||||
| sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x |
|
||||
| spread.js:2:15:2:22 | source() | spread.js:4:8:4:19 | { ...taint } |
|
||||
| spread.js:2:15:2:22 | source() | spread.js:5:8:5:43 | { f: 'h ... orld' } |
|
||||
| spread.js:2:15:2:22 | source() | spread.js:7:8:7:19 | [ ...taint ] |
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:45:8:45:8 | x |
|
||||
| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:48:10:48:10 | x |
|
||||
| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:52:10:52:10 | x |
|
||||
| sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x |
|
||||
| thisAssignments.js:4:17:4:24 | source() | thisAssignments.js:5:10:5:18 | obj.field |
|
||||
| thisAssignments.js:7:19:7:26 | source() | thisAssignments.js:8:10:8:20 | this.field2 |
|
||||
| tst.js:2:13:2:20 | source() | tst.js:4:10:4:10 | x |
|
||||
|
||||
Reference in New Issue
Block a user