Skip to content

Commit 484f761

Browse files
authored
Merge pull request github#12316 from MathiasVP/no-taint-indirect-direct-conflation
C++: Remove indirect -> direct taint-flow
2 parents f9c724d + d93d22b commit 484f761

File tree

47 files changed

+1018
-807
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1018
-807
lines changed

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

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -441,10 +441,6 @@ class OperandNode extends Node, Node0 {
441441
Type stripPointer(Type t) {
442442
result = any(Ssa::Indirection ind | ind.getType() = t).getBaseType()
443443
or
444-
// These types have a sensible base type, but don't receive additional
445-
// dataflow nodes representing their indirections. So for now we special case them.
446-
result = t.(ArrayType).getBaseType()
447-
or
448444
result = t.(PointerToMemberType).getBaseType()
449445
or
450446
result = t.(FunctionPointerIshType).getBaseType()
@@ -813,7 +809,7 @@ private class PostIndirectReturnOutNode extends IndirectReturnOutNode, PostUpdat
813809
*
814810
* Returns `t`, but stripped of the outer-most `indirectionIndex` number of indirections.
815811
*/
816-
Type getTypeImpl(Type t, int indirectionIndex) {
812+
private Type getTypeImpl0(Type t, int indirectionIndex) {
817813
indirectionIndex = 0 and
818814
result = t
819815
or
@@ -823,12 +819,30 @@ Type getTypeImpl(Type t, int indirectionIndex) {
823819
// We need to avoid the case where `stripPointer(t) = t` (which can happen on
824820
// iterators that specify a `value_type` that is the iterator itself). Such a type
825821
// would create an infinite loop otherwise. For these cases we simply don't produce
826-
// a result for `getType`.
822+
// a result for `getTypeImpl`.
827823
stripped.getUnspecifiedType() != t.getUnspecifiedType() and
828-
result = getTypeImpl(stripped, indirectionIndex - 1)
824+
result = getTypeImpl0(stripped, indirectionIndex - 1)
829825
)
830826
}
831827

828+
/**
829+
* INTERNAL: Do not use.
830+
*
831+
* Returns `t`, but stripped of the outer-most `indirectionIndex` number of indirections.
832+
*
833+
* If `indirectionIndex` cannot be stripped off `t`, an `UnknownType` is returned.
834+
*/
835+
bindingset[indirectionIndex]
836+
Type getTypeImpl(Type t, int indirectionIndex) {
837+
result = getTypeImpl0(t, indirectionIndex)
838+
or
839+
// If we cannot produce the right type we return an error type.
840+
// This can sometimes happen when we don't know the real
841+
// type of a void pointer.
842+
not exists(getTypeImpl0(t, indirectionIndex)) and
843+
result instanceof UnknownType
844+
}
845+
832846
/**
833847
* INTERNAL: Do not use.
834848
*
@@ -988,7 +1002,7 @@ private predicate indirectExprNodeShouldBeIndirectOperand(RawIndirectOperand nod
9881002
e = e0.getFullyConverted()
9891003
)
9901004
or
991-
not indirectExprNodeShouldBeIndirectOperand0(_, _, e.getUnconverted()) and
1005+
not indirectExprNodeShouldBeIndirectOperand0(_, node, _) and
9921006
e = instr.getConvertedResultExpression()
9931007
)
9941008
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ private import semmle.code.cpp.ir.dataflow.TaintTracking
1919
private import semmle.code.cpp.ir.dataflow.TaintTracking2
2020
private import semmle.code.cpp.ir.dataflow.TaintTracking3
2121
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
22+
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
2223

2324
/**
2425
* A predictable instruction is one where an external user can predict
@@ -75,6 +76,20 @@ private DataFlow::Node getNodeForExpr(Expr node) {
7576
not argv(node.(VariableAccess).getTarget())
7677
}
7778

79+
private predicate conflatePointerAndPointee(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
80+
// Flow from `op` to `*op`.
81+
exists(Operand operand, int indirectionIndex |
82+
nodeHasOperand(nodeFrom, operand, indirectionIndex) and
83+
nodeHasOperand(nodeTo, operand, indirectionIndex - 1)
84+
)
85+
or
86+
// Flow from `instr` to `*instr`.
87+
exists(Instruction instr, int indirectionIndex |
88+
nodeHasInstruction(nodeFrom, instr, indirectionIndex) and
89+
nodeHasInstruction(nodeTo, instr, indirectionIndex - 1)
90+
)
91+
}
92+
7893
private class DefaultTaintTrackingCfg extends TaintTracking::Configuration {
7994
DefaultTaintTrackingCfg() { this = "DefaultTaintTrackingCfg" }
8095

@@ -85,6 +100,10 @@ private class DefaultTaintTrackingCfg extends TaintTracking::Configuration {
85100
override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) }
86101

87102
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
103+
104+
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
105+
conflatePointerAndPointee(nodeFrom, nodeTo)
106+
}
88107
}
89108

90109
private class ToGlobalVarTaintTrackingCfg extends TaintTracking::Configuration {
@@ -417,6 +436,8 @@ module TaintedWithPath {
417436
}
418437

419438
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
439+
conflatePointerAndPointee(n1, n2)
440+
or
420441
// Steps into and out of global variables
421442
exists(TaintTrackingConfiguration cfg | cfg.taintThroughGlobals() |
422443
writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable))

0 commit comments

Comments
 (0)