Skip to content

Commit 5a027b9

Browse files
committed
Dataflow: Duplicate accesspath type info in PathNode and pathStep.
1 parent 209d914 commit 5a027b9

File tree

1 file changed

+65
-48
lines changed

1 file changed

+65
-48
lines changed

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,9 +2666,12 @@ module Impl<FullStateConfigSig Config> {
26662666

26672667
private newtype TSummaryCtx =
26682668
TSummaryCtxNone() or
2669-
TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) {
2670-
Stage5::parameterMayFlowThrough(p, ap.getApprox()) and
2671-
Stage5::revFlow(p, state, _)
2669+
TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) {
2670+
exists(AccessPathApprox apa | ap.getApprox() = apa |
2671+
Stage5::parameterMayFlowThrough(p, apa) and
2672+
Stage5::fwdFlow(p, state, _, _, _, t, apa) and
2673+
Stage5::revFlow(p, state, _)
2674+
)
26722675
}
26732676

26742677
/**
@@ -2690,9 +2693,10 @@ module Impl<FullStateConfigSig Config> {
26902693
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
26912694
private ParamNodeEx p;
26922695
private FlowState s;
2696+
private DataFlowType t;
26932697
private AccessPath ap;
26942698

2695-
SummaryCtxSome() { this = TSummaryCtxSome(p, s, ap) }
2699+
SummaryCtxSome() { this = TSummaryCtxSome(p, s, t, ap) }
26962700

26972701
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
26982702

@@ -2823,16 +2827,17 @@ module Impl<FullStateConfigSig Config> {
28232827

28242828
private newtype TPathNode =
28252829
pragma[assume_small_delta]
2826-
TPathNodeMid(NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap) {
2830+
TPathNodeMid(NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap) {
28272831
// A PathNode is introduced by a source ...
28282832
Stage5::revFlow(node, state) and
28292833
sourceNode(node, state) and
28302834
sourceCallCtx(cc) and
28312835
sc instanceof SummaryCtxNone and
2832-
ap = TAccessPathNil(node.getDataFlowType())
2836+
t = node.getDataFlowType() and
2837+
ap = TAccessPathNil(t)
28332838
or
28342839
// ... or a step from an existing PathNode to another node.
2835-
pathStep(_, node, state, cc, sc, ap) and
2840+
pathStep(_, node, state, cc, sc, t, ap) and
28362841
Stage5::revFlow(node, state, ap.getApprox())
28372842
} or
28382843
TPathNodeSink(NodeEx node, FlowState state) {
@@ -3215,9 +3220,10 @@ module Impl<FullStateConfigSig Config> {
32153220
FlowState state;
32163221
CallContext cc;
32173222
SummaryCtx sc;
3223+
DataFlowType t;
32183224
AccessPath ap;
32193225

3220-
PathNodeMid() { this = TPathNodeMid(node, state, cc, sc, ap) }
3226+
PathNodeMid() { this = TPathNodeMid(node, state, cc, sc, t, ap) }
32213227

32223228
override NodeEx getNodeEx() { result = node }
32233229

@@ -3227,11 +3233,13 @@ module Impl<FullStateConfigSig Config> {
32273233

32283234
SummaryCtx getSummaryCtx() { result = sc }
32293235

3236+
DataFlowType getType() { result = t }
3237+
32303238
AccessPath getAp() { result = ap }
32313239

32323240
private PathNodeMid getSuccMid() {
32333241
pathStep(this, result.getNodeEx(), result.getState(), result.getCallContext(),
3234-
result.getSummaryCtx(), result.getAp())
3242+
result.getSummaryCtx(), result.getType(), result.getAp())
32353243
}
32363244

32373245
override PathNodeImpl getASuccessorImpl() {
@@ -3246,7 +3254,8 @@ module Impl<FullStateConfigSig Config> {
32463254
sourceNode(node, state) and
32473255
sourceCallCtx(cc) and
32483256
sc instanceof SummaryCtxNone and
3249-
ap = TAccessPathNil(node.getDataFlowType())
3257+
t = node.getDataFlowType() and
3258+
ap = TAccessPathNil(t)
32503259
}
32513260

32523261
predicate isAtSink() {
@@ -3343,7 +3352,7 @@ module Impl<FullStateConfigSig Config> {
33433352
}
33443353

33453354
private predicate pathNode(
3346-
PathNodeMid mid, NodeEx midnode, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap,
3355+
PathNodeMid mid, NodeEx midnode, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap,
33473356
LocalCallContext localCC
33483357
) {
33493358
midnode = mid.getNodeEx() and
@@ -3353,6 +3362,7 @@ module Impl<FullStateConfigSig Config> {
33533362
localCC =
33543363
getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)),
33553364
midnode.getEnclosingCallable()) and
3365+
t = mid.getType() and
33563366
ap = mid.getAp()
33573367
}
33583368

@@ -3363,49 +3373,56 @@ module Impl<FullStateConfigSig Config> {
33633373
pragma[assume_small_delta]
33643374
pragma[nomagic]
33653375
private predicate pathStep(
3366-
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap
3376+
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap
33673377
) {
33683378
exists(NodeEx midnode, FlowState state0, LocalCallContext localCC |
3369-
pathNode(mid, midnode, state0, cc, sc, ap, localCC) and
3379+
pathNode(mid, midnode, state0, cc, sc, t, ap, localCC) and
33703380
localFlowBigStep(midnode, state0, node, state, true, _, localCC)
33713381
)
33723382
or
33733383
exists(AccessPath ap0, NodeEx midnode, FlowState state0, LocalCallContext localCC |
3374-
pathNode(mid, midnode, state0, cc, sc, ap0, localCC) and
3375-
localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), localCC) and
3384+
pathNode(mid, midnode, state0, cc, sc, _, ap0, localCC) and
3385+
localFlowBigStep(midnode, state0, node, state, false, t, localCC) and
3386+
ap.(AccessPathNil).getType() = t and
33763387
ap0 instanceof AccessPathNil
33773388
)
33783389
or
33793390
jumpStepEx(mid.getNodeEx(), node) and
33803391
state = mid.getState() and
33813392
cc instanceof CallContextAny and
33823393
sc instanceof SummaryCtxNone and
3394+
t = mid.getType() and
33833395
ap = mid.getAp()
33843396
or
33853397
additionalJumpStep(mid.getNodeEx(), node) and
33863398
state = mid.getState() and
33873399
cc instanceof CallContextAny and
33883400
sc instanceof SummaryCtxNone and
33893401
mid.getAp() instanceof AccessPathNil and
3390-
ap = TAccessPathNil(node.getDataFlowType())
3402+
t = node.getDataFlowType() and
3403+
ap = TAccessPathNil(t)
33913404
or
33923405
additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state) and
33933406
cc instanceof CallContextAny and
33943407
sc instanceof SummaryCtxNone and
33953408
mid.getAp() instanceof AccessPathNil and
3396-
ap = TAccessPathNil(node.getDataFlowType())
3409+
t = node.getDataFlowType() and
3410+
ap = TAccessPathNil(t)
33973411
or
3398-
exists(TypedContent tc | pathStoreStep(mid, node, state, ap.pop(tc), tc, cc)) and
3412+
exists(TypedContent tc | pathStoreStep(mid, node, state, ap.pop(tc), tc, t, cc)) and
33993413
sc = mid.getSummaryCtx()
34003414
or
34013415
exists(TypedContent tc | pathReadStep(mid, node, state, ap.push(tc), tc, cc)) and
3416+
// TODO: replace push/pop with isCons
3417+
// ap0.isCons(tc, t, ap)
3418+
exists(t) and
34023419
sc = mid.getSummaryCtx()
34033420
or
3404-
pathIntoCallable(mid, node, state, _, cc, sc, _) and ap = mid.getAp()
3421+
pathIntoCallable(mid, node, state, _, cc, sc, _) and t = mid.getType() and ap = mid.getAp()
34053422
or
3406-
pathOutOfCallable(mid, node, state, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
3423+
pathOutOfCallable(mid, node, state, cc) and t = mid.getType() and ap = mid.getAp() and sc instanceof SummaryCtxNone
34073424
or
3408-
pathThroughCallable(mid, node, state, cc, ap) and sc = mid.getSummaryCtx()
3425+
pathThroughCallable(mid, node, state, cc, t, ap) and sc = mid.getSummaryCtx()
34093426
}
34103427

34113428
pragma[nomagic]
@@ -3421,10 +3438,10 @@ module Impl<FullStateConfigSig Config> {
34213438

34223439
pragma[nomagic]
34233440
private predicate pathStoreStep(
3424-
PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc
3441+
PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, DataFlowType t, CallContext cc
34253442
) {
34263443
ap0 = mid.getAp() and
3427-
Stage5::storeStepCand(mid.getNodeEx(), _, tc, _, node, _, _) and
3444+
Stage5::storeStepCand(mid.getNodeEx(), _, tc, _, node, _, t) and
34283445
state = mid.getState() and
34293446
cc = mid.getCallContext()
34303447
}
@@ -3478,10 +3495,10 @@ module Impl<FullStateConfigSig Config> {
34783495
pragma[noinline]
34793496
private predicate pathIntoArg(
34803497
PathNodeMid mid, ParameterPosition ppos, FlowState state, CallContext cc, DataFlowCall call,
3481-
AccessPath ap, AccessPathApprox apa
3498+
DataFlowType t, AccessPath ap, AccessPathApprox apa
34823499
) {
34833500
exists(ArgNodeEx arg, ArgumentPosition apos |
3484-
pathNode(mid, arg, state, cc, _, ap, _) and
3501+
pathNode(mid, arg, state, cc, _, t, ap, _) and
34853502
arg.asNode().(ArgNode).argumentOf(call, apos) and
34863503
apa = ap.getApprox() and
34873504
parameterMatch(ppos, apos)
@@ -3501,10 +3518,10 @@ module Impl<FullStateConfigSig Config> {
35013518
pragma[nomagic]
35023519
private predicate pathIntoCallable0(
35033520
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, FlowState state,
3504-
CallContext outercc, DataFlowCall call, AccessPath ap
3521+
CallContext outercc, DataFlowCall call, DataFlowType t, AccessPath ap
35053522
) {
35063523
exists(AccessPathApprox apa |
3507-
pathIntoArg(mid, pragma[only_bind_into](pos), state, outercc, call, ap,
3524+
pathIntoArg(mid, pragma[only_bind_into](pos), state, outercc, call, t, ap,
35083525
pragma[only_bind_into](apa)) and
35093526
callable = resolveCall(call, outercc) and
35103527
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa))
@@ -3521,13 +3538,13 @@ module Impl<FullStateConfigSig Config> {
35213538
PathNodeMid mid, ParamNodeEx p, FlowState state, CallContext outercc, CallContextCall innercc,
35223539
SummaryCtx sc, DataFlowCall call
35233540
) {
3524-
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
3525-
pathIntoCallable0(mid, callable, pos, state, outercc, call, ap) and
3541+
exists(ParameterPosition pos, DataFlowCallable callable, DataFlowType t, AccessPath ap |
3542+
pathIntoCallable0(mid, callable, pos, state, outercc, call, t, ap) and
35263543
p.isParameterOf(callable, pos) and
35273544
(
3528-
sc = TSummaryCtxSome(p, state, ap)
3545+
sc = TSummaryCtxSome(p, state, t, ap)
35293546
or
3530-
not exists(TSummaryCtxSome(p, state, ap)) and
3547+
not exists(TSummaryCtxSome(p, state, t, ap)) and
35313548
sc = TSummaryCtxNone() and
35323549
// When the call contexts of source and sink needs to match then there's
35333550
// never any reason to enter a callable except to find a summary. See also
@@ -3544,11 +3561,11 @@ module Impl<FullStateConfigSig Config> {
35443561
/** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */
35453562
pragma[nomagic]
35463563
private predicate paramFlowsThrough(
3547-
ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap,
3564+
ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, DataFlowType t, AccessPath ap,
35483565
AccessPathApprox apa
35493566
) {
35503567
exists(RetNodeEx ret |
3551-
pathNode(_, ret, state, cc, sc, ap, _) and
3568+
pathNode(_, ret, state, cc, sc, t, ap, _) and
35523569
kind = ret.getKind() and
35533570
apa = ap.getApprox() and
35543571
parameterFlowThroughAllowed(sc.getParamNode(), kind)
@@ -3559,11 +3576,11 @@ module Impl<FullStateConfigSig Config> {
35593576
pragma[nomagic]
35603577
private predicate pathThroughCallable0(
35613578
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc,
3562-
AccessPath ap, AccessPathApprox apa
3579+
DataFlowType t, AccessPath ap, AccessPathApprox apa
35633580
) {
35643581
exists(CallContext innercc, SummaryCtx sc |
35653582
pathIntoCallable(mid, _, _, cc, innercc, sc, call) and
3566-
paramFlowsThrough(kind, state, innercc, sc, ap, apa)
3583+
paramFlowsThrough(kind, state, innercc, sc, t, ap, apa)
35673584
)
35683585
}
35693586

@@ -3573,10 +3590,10 @@ module Impl<FullStateConfigSig Config> {
35733590
*/
35743591
pragma[noinline]
35753592
private predicate pathThroughCallable(
3576-
PathNodeMid mid, NodeEx out, FlowState state, CallContext cc, AccessPath ap
3593+
PathNodeMid mid, NodeEx out, FlowState state, CallContext cc, DataFlowType t, AccessPath ap
35773594
) {
35783595
exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
3579-
pathThroughCallable0(call, mid, kind, state, cc, ap, apa) and
3596+
pathThroughCallable0(call, mid, kind, state, cc, t, ap, apa) and
35803597
out = getAnOutNodeFlow(kind, call, apa)
35813598
)
35823599
}
@@ -3589,12 +3606,12 @@ module Impl<FullStateConfigSig Config> {
35893606
pragma[nomagic]
35903607
private predicate subpaths01(
35913608
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3592-
NodeEx out, FlowState sout, AccessPath apout
3609+
NodeEx out, FlowState sout, DataFlowType t, AccessPath apout
35933610
) {
3594-
pathThroughCallable(arg, out, pragma[only_bind_into](sout), _, pragma[only_bind_into](apout)) and
3611+
pathThroughCallable(arg, out, pragma[only_bind_into](sout), _, pragma[only_bind_into](t), pragma[only_bind_into](apout)) and
35953612
pathIntoCallable(arg, par, _, _, innercc, sc, _) and
35963613
paramFlowsThrough(kind, pragma[only_bind_into](sout), innercc, sc,
3597-
pragma[only_bind_into](apout), _) and
3614+
pragma[only_bind_into](t), pragma[only_bind_into](apout), _) and
35983615
not arg.isHidden()
35993616
}
36003617

@@ -3605,9 +3622,9 @@ module Impl<FullStateConfigSig Config> {
36053622
pragma[nomagic]
36063623
private predicate subpaths02(
36073624
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3608-
NodeEx out, FlowState sout, AccessPath apout
3625+
NodeEx out, FlowState sout, DataFlowType t, AccessPath apout
36093626
) {
3610-
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
3627+
subpaths01(arg, par, sc, innercc, kind, out, sout, t, apout) and
36113628
out.asNode() = kind.getAnOutNode(_)
36123629
}
36133630

@@ -3617,11 +3634,11 @@ module Impl<FullStateConfigSig Config> {
36173634
pragma[nomagic]
36183635
private predicate subpaths03(
36193636
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout,
3620-
AccessPath apout
3637+
DataFlowType t, AccessPath apout
36213638
) {
36223639
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
3623-
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
3624-
pathNode(ret, retnode, sout, innercc, sc, apout, _) and
3640+
subpaths02(arg, par, sc, innercc, kind, out, sout, t, apout) and
3641+
pathNode(ret, retnode, sout, innercc, sc, t, apout, _) and
36253642
kind = retnode.getKind()
36263643
)
36273644
}
@@ -3648,12 +3665,12 @@ module Impl<FullStateConfigSig Config> {
36483665
* `ret -> out` is summarized as the edge `arg -> out`.
36493666
*/
36503667
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
3651-
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
3668+
exists(ParamNodeEx p, NodeEx o, FlowState sout, DataFlowType t, AccessPath apout, PathNodeMid out0 |
36523669
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
3653-
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
3670+
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, t, apout) and
36543671
hasSuccessor(pragma[only_bind_into](arg), par, p) and
36553672
not ret.isHidden() and
3656-
pathNode(out0, o, sout, _, _, apout, _)
3673+
pathNode(out0, o, sout, _, _, t, apout, _)
36573674
|
36583675
out = out0 or out = out0.projectToSink()
36593676
)

0 commit comments

Comments
 (0)