Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b951bf0
C++: Remove conflation from taint-tracking.
MathiasVP Feb 21, 2023
64abf5b
C++: Add conflation into DefaultTaintTracking.
MathiasVP Feb 21, 2023
5a8b900
C++: Properly track smart pointer wrappers.
MathiasVP Feb 21, 2023
a806569
C++: The next commit is going to track flow out of both direct and in…
MathiasVP Feb 21, 2023
09df318
C++: Also track flow out of indirect sources.
MathiasVP Feb 21, 2023
2cb4a55
C++: Fix a bug in Expr <-> Node mapping.
MathiasVP Feb 21, 2023
1e4caca
C++: Accept query changes. Nothing bad to see here.
MathiasVP Feb 21, 2023
9d64c0a
C++: Add failing test.
MathiasVP Feb 26, 2023
057e810
C++: Fix flow through arrays.
MathiasVP Feb 24, 2023
b952f61
C++: Accept test changes.
MathiasVP Feb 24, 2023
575ac46
C++: Add failing test.
MathiasVP Feb 26, 2023
52e6e1d
C++: Fix flow through partial definitions.
MathiasVP Feb 25, 2023
da4a059
C++: Accept test changes.
MathiasVP Feb 26, 2023
f6b9ca3
C++: Add failing test.
MathiasVP Feb 26, 2023
16ba465
C++: Allocate an additional indirection for void pointers.
MathiasVP Feb 25, 2023
4e16bb6
C++: Accept test changes. Because we now allocate _three_ indirect nodes
MathiasVP Feb 25, 2023
1db24dd
C++: Fix missing types. We now assign the node corresponding to `**p`
MathiasVP Feb 26, 2023
354a12c
C++: Fix queries. Since there's no longer indirect -> direct flow in
MathiasVP Feb 26, 2023
31f3504
C++: Remove this bad materialization:
MathiasVP Feb 26, 2023
b36d493
C++: Fix test annotation.
MathiasVP Feb 27, 2023
7bb8065
Merge branch 'mathiasvp/replace-ast-with-ir-use-usedataflow' into no-…
MathiasVP Feb 27, 2023
3906a19
Merge branch 'mathiasvp/replace-ast-with-ir-use-usedataflow' into no-…
MathiasVP Feb 27, 2023
04b8432
C++: Accept more query-test changes.
MathiasVP Feb 27, 2023
85c7116
C++: Fix the following join (I canceled it mid-way):
MathiasVP Feb 28, 2023
1e5b235
C++: Accept test changes in 'cpp/non-constant-format'. These are actu…
MathiasVP Feb 28, 2023
d93d22b
C++: Fix FPs in 'cpp/non-constant-format'.
MathiasVP Feb 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Original file line number Diff line number Diff line change
Expand Up @@ -441,10 +441,6 @@ class OperandNode extends Node, Node0 {
Type stripPointer(Type t) {
result = any(Ssa::Indirection ind | ind.getType() = t).getBaseType()
or
// These types have a sensible base type, but don't receive additional
// dataflow nodes representing their indirections. So for now we special case them.
result = t.(ArrayType).getBaseType()
or
result = t.(PointerToMemberType).getBaseType()
or
result = t.(FunctionPointerIshType).getBaseType()
Expand Down Expand Up @@ -813,7 +809,7 @@ private class PostIndirectReturnOutNode extends IndirectReturnOutNode, PostUpdat
*
* Returns `t`, but stripped of the outer-most `indirectionIndex` number of indirections.
*/
Type getTypeImpl(Type t, int indirectionIndex) {
private Type getTypeImpl0(Type t, int indirectionIndex) {
indirectionIndex = 0 and
result = t
or
Expand All @@ -823,12 +819,30 @@ Type getTypeImpl(Type t, int indirectionIndex) {
// We need to avoid the case where `stripPointer(t) = t` (which can happen on
// iterators that specify a `value_type` that is the iterator itself). Such a type
// would create an infinite loop otherwise. For these cases we simply don't produce
// a result for `getType`.
// a result for `getTypeImpl`.
stripped.getUnspecifiedType() != t.getUnspecifiedType() and
result = getTypeImpl(stripped, indirectionIndex - 1)
result = getTypeImpl0(stripped, indirectionIndex - 1)
)
}

/**
* INTERNAL: Do not use.
*
* Returns `t`, but stripped of the outer-most `indirectionIndex` number of indirections.
*
* If `indirectionIndex` cannot be stripped off `t`, an `UnknownType` is returned.
*/
bindingset[indirectionIndex]
Type getTypeImpl(Type t, int indirectionIndex) {
result = getTypeImpl0(t, indirectionIndex)
or
// If we cannot produce the right type we return an error type.
// This can sometimes happen when we don't know the real
// type of a void pointer.
not exists(getTypeImpl0(t, indirectionIndex)) and
result instanceof UnknownType
}

/**
* INTERNAL: Do not use.
*
Expand Down Expand Up @@ -988,7 +1002,7 @@ private predicate indirectExprNodeShouldBeIndirectOperand(RawIndirectOperand nod
e = e0.getFullyConverted()
)
or
not indirectExprNodeShouldBeIndirectOperand0(_, _, e.getUnconverted()) and
not indirectExprNodeShouldBeIndirectOperand0(_, node, _) and
e = instr.getConvertedResultExpression()
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ private import semmle.code.cpp.ir.dataflow.TaintTracking
private import semmle.code.cpp.ir.dataflow.TaintTracking2
private import semmle.code.cpp.ir.dataflow.TaintTracking3
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate

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

private predicate conflatePointerAndPointee(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
// Flow from `op` to `*op`.
exists(Operand operand, int indirectionIndex |
nodeHasOperand(nodeFrom, operand, indirectionIndex) and
nodeHasOperand(nodeTo, operand, indirectionIndex - 1)
)
or
// Flow from `instr` to `*instr`.
exists(Instruction instr, int indirectionIndex |
nodeHasInstruction(nodeFrom, instr, indirectionIndex) and
nodeHasInstruction(nodeTo, instr, indirectionIndex - 1)
)
}

private class DefaultTaintTrackingCfg extends TaintTracking::Configuration {
DefaultTaintTrackingCfg() { this = "DefaultTaintTrackingCfg" }

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

override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) }

override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
conflatePointerAndPointee(nodeFrom, nodeTo)
}
}

private class ToGlobalVarTaintTrackingCfg extends TaintTracking::Configuration {
Expand Down Expand Up @@ -417,6 +436,8 @@ module TaintedWithPath {
}

override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
conflatePointerAndPointee(n1, n2)
or
// Steps into and out of global variables
exists(TaintTrackingConfiguration cfg | cfg.taintThroughGlobals() |
writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable))
Expand Down
Loading