@@ -2,6 +2,7 @@ private import semmle.code.cpp.ir.IR
2
2
private import semmle.code.cpp.ir.dataflow.DataFlow
3
3
private import ModelUtil
4
4
private import semmle.code.cpp.models.interfaces.DataFlow
5
+ private import semmle.code.cpp.models.interfaces.SideEffect
5
6
6
7
/**
7
8
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
@@ -49,6 +50,23 @@ private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction no
49
50
nodeTo .( LoadInstruction ) .getSourceAddress ( ) = nodeFrom
50
51
or
51
52
modeledInstructionTaintStep ( nodeFrom , nodeTo )
53
+ or
54
+ // Flow through partial reads of arrays and unions
55
+ nodeTo .( LoadInstruction ) .getSourceValueOperand ( ) .getAnyDef ( ) = nodeFrom and
56
+ not nodeFrom .isResultConflated ( ) and
57
+ (
58
+ nodeFrom .getResultType ( ) instanceof ArrayType or
59
+ nodeFrom .getResultType ( ) instanceof Union
60
+ )
61
+ or
62
+ // Flow from an element to an array or union that contains it.
63
+ nodeTo .( ChiInstruction ) .getPartial ( ) = nodeFrom and
64
+ not nodeTo .isResultConflated ( ) and
65
+ exists ( Type t | nodeTo .getResultLanguageType ( ) .hasType ( t , false ) |
66
+ t instanceof Union
67
+ or
68
+ t instanceof ArrayType
69
+ )
52
70
}
53
71
54
72
/**
@@ -104,7 +122,10 @@ predicate modeledInstructionTaintStep(Instruction instrIn, Instruction instrOut)
104
122
// could model this flow in two separate steps, but that would add reverse
105
123
// flow from the write side-effect to the call instruction, which may not be
106
124
// desirable.
107
- exists ( CallInstruction call , Function func , FunctionInput modelIn , OutParameterDeref modelMidOut , int indexMid , InParameter modelMidIn , OutReturnValue modelOut |
125
+ exists (
126
+ CallInstruction call , Function func , FunctionInput modelIn , OutParameterDeref modelMidOut ,
127
+ int indexMid , InParameter modelMidIn , OutReturnValue modelOut
128
+ |
108
129
instrIn = callInput ( call , modelIn ) and
109
130
instrOut = callOutput ( call , modelOut ) and
110
131
call .getStaticCallTarget ( ) = func and
0 commit comments