Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8f4982d

Browse files
committed
C++: Remove flow into ReadSideEffect instructions in simpleInstructionLocalFlowStep
1 parent aa707e9 commit 8f4982d

3 files changed

Lines changed: 58 additions & 27 deletions

File tree

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,33 @@ private import DataFlowDispatch
77
* A data flow node that occurs as the argument of a call and is passed as-is
88
* to the callable. Instance arguments (`this` pointer) are also included.
99
*/
10-
class ArgumentNode extends InstructionNode {
10+
class ArgumentNode extends Node {
1111
ArgumentNode() {
12-
exists(CallInstruction call |
13-
instr = call.getAnArgument()
14-
or
15-
instr.(ReadSideEffectInstruction).getPrimaryInstruction() = call
16-
)
12+
// To avoid making this class abstract, we enumerate its values here.
13+
this instanceof PrimaryArgumentNode or
14+
this instanceof SideEffectArgumentNode
15+
}
16+
17+
/**
18+
* Holds if this argument occurs at the given position in the given call.
19+
* The instance argument is considered to have index `-1`.
20+
*/
21+
predicate argumentOf(DataFlowCall call, int pos) {
22+
this.(PrimaryArgumentNode).argumentOf(call, pos) or
23+
this.(SideEffectArgumentNode).argumentOf(call, pos)
1724
}
1825

26+
/** Gets the call in which this node is an argument. */
27+
DataFlowCall getCall() { this.argumentOf(result, _) }
28+
}
29+
30+
/**
31+
* A data flow node that occurs as the argument to a call, or an
32+
* implicit `this` pointer argument.
33+
*/
34+
private class PrimaryArgumentNode extends InstructionNode {
35+
PrimaryArgumentNode() { exists(CallInstruction call | instr = call.getAnArgument()) }
36+
1937
/**
2038
* Holds if this argument occurs at the given position in the given call.
2139
* The instance argument is considered to have index `-1`.
@@ -24,16 +42,33 @@ class ArgumentNode extends InstructionNode {
2442
instr = call.getPositionalArgument(pos)
2543
or
2644
instr = call.getThisArgument() and pos = -1
27-
or
28-
exists(ReadSideEffectInstruction read |
29-
read = instr and
45+
}
46+
}
47+
48+
/**
49+
* A data flow node representing the read side effect of a call on a
50+
* specific parameter.
51+
*/
52+
private class SideEffectArgumentNode extends OperandNode {
53+
override SideEffectOperand op;
54+
ReadSideEffectInstruction read;
55+
56+
SideEffectArgumentNode() {
57+
exists(CallInstruction call |
3058
read.getPrimaryInstruction() = call and
31-
pos = getArgumentPosOfSideEffect(read.getIndex())
59+
op = read.getSideEffectOperand()
3260
)
3361
}
3462

35-
/** Gets the call in which this node is an argument. */
36-
DataFlowCall getCall() { this.argumentOf(result, _) }
63+
/**
64+
* Holds if this argument occurs at the given position in the given call.
65+
* See `getArgumentPosOfSideEffect` for a describing of how read side effects
66+
* are assigned an argument position.
67+
*/
68+
predicate argumentOf(DataFlowCall call, int pos) {
69+
read.getPrimaryInstruction() = call and
70+
pos = getArgumentPosOfSideEffect(read.getIndex())
71+
}
3772
}
3873

3974
private newtype TReturnKind =

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -509,12 +509,15 @@ class DefinitionByReferenceNode extends InstructionNode {
509509
* A node representing the memory pointed to by a function argument.
510510
*
511511
* This class exists only in order to override `toString`, which would
512-
* otherwise be the default implementation inherited from `InstructionNode`.
512+
* otherwise be the default implementation inherited from `OperandNode`.
513513
*/
514-
private class ArgumentIndirectionNode extends InstructionNode {
515-
override ReadSideEffectInstruction instr;
514+
private class ArgumentIndirectionNode extends OperandNode {
515+
override SideEffectOperand op;
516+
ReadSideEffectInstruction read;
516517

517-
override string toString() { result = "Argument " + instr.getIndex() + " indirection" }
518+
ArgumentIndirectionNode() { read.getSideEffectOperand() = op }
519+
520+
override string toString() { result = "Argument " + read.getIndex() + " indirection" }
518521
}
519522

520523
/**
@@ -680,10 +683,6 @@ private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo
680683
or
681684
iTo.(PhiInstruction).getAnInputOperand() = opFrom
682685
or
683-
// A read side effect is almost never exact since we don't know exactly how
684-
// much memory the callee will read.
685-
iTo.(ReadSideEffectInstruction).getSideEffectOperand() = opFrom
686-
or
687686
// Treat all conversions as flow, even conversions between different numeric types.
688687
iTo.(ConvertInstruction).getUnaryOperand() = opFrom
689688
or

cpp/ql/test/library-tests/dataflow/taint-tests/IRTaintTestCommon.qll

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,10 @@ class TestAllocationConfig extends TaintTracking::Configuration {
2525
sink.(DataFlow::ExprNode).getConvertedExpr() instanceof ReferenceDereferenceExpr
2626
)
2727
or
28-
sink
29-
.asInstruction()
30-
.(ReadSideEffectInstruction)
31-
.getPrimaryInstruction()
32-
.(CallInstruction)
33-
.getStaticCallTarget()
34-
.hasName("sink")
28+
exists(ReadSideEffectInstruction read |
29+
read.getSideEffectOperand() = sink.asOperand() and
30+
read.getPrimaryInstruction().(CallInstruction).getStaticCallTarget().hasName("sink")
31+
)
3532
}
3633

3734
override predicate isSanitizer(DataFlow::Node barrier) {

0 commit comments

Comments
 (0)