Skip to content

Commit 2dc2607

Browse files
committed
TODO
1 parent 266130b commit 2dc2607

11 files changed

Lines changed: 2126 additions & 2150 deletions

File tree

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowNodes.qll

Lines changed: 1815 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 192 additions & 193 deletions
Large diffs are not rendered by default.

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

Lines changed: 22 additions & 1879 deletions
Large diffs are not rendered by default.

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ExprNodes.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ private import cpp
66
private import semmle.code.cpp.ir.IR
77
private import DataFlowUtil
88
private import DataFlowPrivate
9+
private import DataFlowNodes
910
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
1011
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
1112

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
private import semmle.code.cpp.ir.IR
77
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
88
private import DataFlowUtil
9+
private import DataFlowNodes
910
private import DataFlowPrivate
1011
private import SsaImpl as Ssa
1112

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ private import semmle.code.cpp.ir.internal.IRCppLanguage
1212
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
1313
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedInitialization
1414
private import DataFlowPrivate
15+
private import DataFlowNodes
1516
import SsaImplCommon
1617

1718
private module SourceVariables {

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import semmle.code.cpp.ir.internal.IRCppLanguage
44
private import semmle.code.cpp.ir.implementation.raw.internal.SideEffects as SideEffects
55
private import DataFlowImplCommon as DataFlowImplCommon
66
private import DataFlowUtil
7+
private import DataFlowNodes
78
private import semmle.code.cpp.models.interfaces.PointerWrapper
89
private import DataFlowPrivate
910
private import TypeFlow
@@ -55,26 +56,6 @@ private CppType getThisType(Cpp::MemberFunction f, boolean isGLValue) {
5556
result.hasType(f.getTypeOfThis(), isGLValue)
5657
}
5758

58-
/**
59-
* Gets the C++ type of the instruction `i`.
60-
*
61-
* This is equivalent to `i.getResultLanguageType()` with the exception
62-
* of instructions that directly references a `this` IRVariable. In this
63-
* case, `i.getResultLanguageType()` gives an unknown type, whereas the
64-
* predicate gives the expected type (i.e., a potentially cv-qualified
65-
* type `A*` where `A` is the declaring type of the member function that
66-
* contains `i`).
67-
*/
68-
cached
69-
CppType getResultLanguageType(Instruction i) {
70-
if i.(VariableAddressInstruction).getIRVariable() instanceof IRThisVariable
71-
then
72-
if i.isGLValue()
73-
then result = getThisType(i.getEnclosingFunction(), true)
74-
else result = getThisType(i.getEnclosingFunction(), false)
75-
else result = i.getResultLanguageType()
76-
}
77-
7859
/**
7960
* Gets the C++ type of the operand `operand`.
8061
* This is equivalent to the type of the operand's defining instruction.
@@ -572,6 +553,26 @@ private class BaseCallInstruction extends BaseSourceVariableInstruction, CallIns
572553

573554
cached
574555
private module Cached {
556+
/**
557+
* Gets the C++ type of the instruction `i`.
558+
*
559+
* This is equivalent to `i.getResultLanguageType()` with the exception
560+
* of instructions that directly references a `this` IRVariable. In this
561+
* case, `i.getResultLanguageType()` gives an unknown type, whereas the
562+
* predicate gives the expected type (i.e., a potentially cv-qualified
563+
* type `A*` where `A` is the declaring type of the member function that
564+
* contains `i`).
565+
*/
566+
cached
567+
CppType getResultLanguageType(Instruction i) {
568+
if i.(VariableAddressInstruction).getIRVariable() instanceof IRThisVariable
569+
then
570+
if i.isGLValue()
571+
then result = getThisType(i.getEnclosingFunction(), true)
572+
else result = getThisType(i.getEnclosingFunction(), false)
573+
else result = i.getResultLanguageType()
574+
}
575+
575576
/** Holds if `op` is the only use of its defining instruction, and that op is used in a conversation */
576577
private predicate isConversion(Operand op) {
577578
exists(Instruction def, Operand use |

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,65 +5,77 @@ private import semmle.code.cpp.models.interfaces.DataFlow
55
private import semmle.code.cpp.models.interfaces.SideEffect
66
private import DataFlowUtil
77
private import DataFlowPrivate
8+
private import DataFlowNodes
89
private import SsaImpl as Ssa
910
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
1011
private import semmle.code.cpp.ir.dataflow.FlowSteps
1112

12-
/**
13-
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
14-
* (intra-procedural) step. This relation is only used for local taint flow
15-
* (for example `TaintTracking::localTaint(source, sink)`) so it may contain
16-
* special cases that should only apply to local taint flow.
17-
*/
18-
predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
19-
// dataflow step
20-
DataFlow::localFlowStep(nodeFrom, nodeTo)
21-
or
22-
// taint flow step
23-
localAdditionalTaintStep(nodeFrom, nodeTo, _)
24-
or
25-
// models-as-data summarized flow for local data flow (i.e. special case for flow
26-
// through calls to modeled functions, without relying on global dataflow to join
27-
// the dots).
28-
FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(nodeFrom, nodeTo, _)
29-
}
30-
31-
/**
32-
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
33-
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
34-
* different objects.
35-
*/
3613
cached
37-
predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, string model) {
38-
operandToInstructionTaintStep(nodeFrom.asOperand(), nodeTo.asInstruction()) and
39-
model = ""
40-
or
41-
modeledTaintStep(nodeFrom, nodeTo, model)
42-
or
43-
// Flow from (the indirection of) an operand of a pointer arithmetic instruction to the
44-
// indirection of the pointer arithmetic instruction. This provides flow from `source`
45-
// in `x[source]` to the result of the associated load instruction.
46-
exists(PointerArithmeticInstruction pai, int indirectionIndex |
47-
nodeHasOperand(nodeFrom, pai.getAnOperand(), pragma[only_bind_into](indirectionIndex)) and
48-
hasInstructionAndIndex(nodeTo, pai, indirectionIndex + 1)
49-
) and
50-
model = ""
51-
or
52-
any(Ssa::Indirection ind).isAdditionalTaintStep(nodeFrom, nodeTo) and
53-
model = ""
54-
or
55-
// models-as-data summarized flow
56-
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
57-
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
58-
or
59-
// object->field conflation for content that is a `TaintInheritingContent`.
60-
exists(DataFlow::ContentSet f |
61-
readStep(nodeFrom, f, nodeTo) and
62-
f.getAReadContent() instanceof TaintInheritingContent
63-
) and
64-
model = ""
14+
private module Cached {
15+
private import DataFlowImplCommon as DataFlowImplCommon
16+
17+
cached
18+
predicate forceCachingInSameStage() { DataFlowImplCommon::forceCachingInSameStage() }
19+
20+
/**
21+
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
22+
* (intra-procedural) step. This relation is only used for local taint flow
23+
* (for example `TaintTracking::localTaint(source, sink)`) so it may contain
24+
* special cases that should only apply to local taint flow.
25+
*/
26+
cached
27+
predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
28+
// dataflow step
29+
DataFlow::localFlowStep(nodeFrom, nodeTo)
30+
or
31+
// taint flow step
32+
localAdditionalTaintStep(nodeFrom, nodeTo, _)
33+
or
34+
// models-as-data summarized flow for local data flow (i.e. special case for flow
35+
// through calls to modeled functions, without relying on global dataflow to join
36+
// the dots).
37+
FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(nodeFrom, nodeTo, _)
38+
}
39+
40+
/**
41+
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
42+
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
43+
* different objects.
44+
*/
45+
cached
46+
predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, string model) {
47+
operandToInstructionTaintStep(nodeFrom.asOperand(), nodeTo.asInstruction()) and
48+
model = ""
49+
or
50+
modeledTaintStep(nodeFrom, nodeTo, model)
51+
or
52+
// Flow from (the indirection of) an operand of a pointer arithmetic instruction to the
53+
// indirection of the pointer arithmetic instruction. This provides flow from `source`
54+
// in `x[source]` to the result of the associated load instruction.
55+
exists(PointerArithmeticInstruction pai, int indirectionIndex |
56+
nodeHasOperand(nodeFrom, pai.getAnOperand(), pragma[only_bind_into](indirectionIndex)) and
57+
hasInstructionAndIndex(nodeTo, pai, indirectionIndex + 1)
58+
) and
59+
model = ""
60+
or
61+
any(Ssa::Indirection ind).isAdditionalTaintStep(nodeFrom, nodeTo) and
62+
model = ""
63+
or
64+
// models-as-data summarized flow
65+
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
66+
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
67+
or
68+
// object->field conflation for content that is a `TaintInheritingContent`.
69+
exists(DataFlow::ContentSet f |
70+
readStep(nodeFrom, f, nodeTo) and
71+
f.getAReadContent() instanceof TaintInheritingContent
72+
) and
73+
model = ""
74+
}
6575
}
6676

77+
import Cached
78+
6779
/**
6880
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
6981
* (intra-procedural) step.
@@ -196,7 +208,7 @@ predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut, string
196208
// Taint flow from a pointer argument to an output, when the model specifies flow from the deref
197209
// to that output, but the deref is not modeled in the IR for the caller.
198210
exists(
199-
CallInstruction call, DataFlow::SideEffectOperandNode indirectArgument, Function func,
211+
CallInstruction call, SideEffectOperandNode indirectArgument, Function func,
200212
FunctionInput modelIn, FunctionOutput modelOut
201213
|
202214
indirectArgument = callInput(call, modelIn) and

cpp/ql/src/Likely Bugs/Memory Management/AllocaInLoop.ql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import cpp
1616
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
1717
import semmle.code.cpp.ir.dataflow.DataFlow
18+
private import semmle.code.cpp.ir.dataflow.internal.DataFlowNodes
1819

1920
/** Gets a loop that contains `e`. */
2021
Loop getAnEnclosingLoopOfExpr(Expr e) { result = getAnEnclosingLoopOfStmt(e.getEnclosingStmt()) }
@@ -45,9 +46,9 @@ private Expr getExpr(DataFlow::Node node) {
4546
or
4647
result = node.asOperand().getUse().getAst()
4748
or
48-
result = node.(DataFlow::RawIndirectInstruction).getInstruction().getAst()
49+
result = node.(RawIndirectInstruction).getInstruction().getAst()
4950
or
50-
result = node.(DataFlow::RawIndirectOperand).getOperand().getUse().getAst()
51+
result = node.(RawIndirectOperand).getOperand().getUse().getAst()
5152
}
5253

5354
/**
@@ -208,7 +209,7 @@ class LoopWithAlloca extends Stmt {
208209
this.conditionRequiresInequality(va, _, _) and
209210
DataFlow::localFlow(result, DataFlow::exprNode(va)) and
210211
// Phi nodes will be preceded by nodes that represent actual definitions
211-
not result instanceof DataFlow::SsaSynthNode and
212+
not result instanceof SsaSynthNode and
212213
// A source is outside the loop if it's not inside the loop
213214
not exists(Expr e | e = getExpr(result) | this = getAnEnclosingLoopOfExpr(e))
214215
)

cpp/ql/src/utils/modelgenerator/internal/CaptureModels.qll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ private import semmle.code.cpp.dataflow.ExternalFlow as ExternalFlow
88
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
99
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific
1010
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as DataFlowPrivate
11+
private import semmle.code.cpp.ir.dataflow.internal.DataFlowNodes as DataFlowNodes
1112
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
1213
private import semmle.code.cpp.ir.dataflow.internal.TaintTrackingImplSpecific
1314
private import semmle.code.cpp.dataflow.new.TaintTracking as Tt
@@ -403,7 +404,7 @@ private module SinkModelGeneratorInput implements SinkModelGeneratorInputSig {
403404
}
404405

405406
predicate apiSource(DataFlow::Node source) {
406-
DataFlowPrivate::nodeHasOperand(source, any(DataFlow::FieldAddress fa), 1)
407+
DataFlowPrivate::nodeHasOperand(source, any(DataFlowNodes::FieldAddress fa), 1)
407408
or
408409
source instanceof DataFlow::ParameterNode
409410
}
@@ -416,7 +417,7 @@ private module SinkModelGeneratorInput implements SinkModelGeneratorInputSig {
416417
result = "Argument[" + DataFlow::repeatStars(indirectionIndex) + argumentIndex + "]"
417418
)
418419
or
419-
DataFlowPrivate::nodeHasOperand(source, any(DataFlow::FieldAddress fa), 1) and
420+
DataFlowPrivate::nodeHasOperand(source, any(DataFlowNodes::FieldAddress fa), 1) and
420421
result = qualifierString()
421422
}
422423

0 commit comments

Comments
 (0)