@@ -78,28 +78,39 @@ predicate isInvalidPointerDerefSink2(DataFlow::Node sink, Instruction i, string
7878 )
7979}
8080
81+ predicate arrayTypeCand ( ArrayType arrayType ) { any ( Variable v ) .getUnspecifiedType ( ) = arrayType }
82+
8183pragma [ nomagic]
8284predicate arrayTypeHasSizes ( ArrayType arr , int baseTypeSize , int arraySize ) {
85+ arrayTypeCand ( arr ) and
8386 arr .getBaseType ( ) .getSize ( ) = baseTypeSize and
8487 arr .getArraySize ( ) = arraySize
8588}
8689
87- predicate pointerArithOverflow0 (
88- PointerArithmeticInstruction pai , Variable v , int size , int bound , int delta
89- ) {
90- not v .getNamespace ( ) instanceof StdNamespace and
91- arrayTypeHasSizes ( v .getUnspecifiedType ( ) , pai .getElementSize ( ) , size ) and
92- semBounded ( getSemanticExpr ( pai .getRight ( ) ) , any ( SemZeroBound b ) , bound , true , _) and
90+ bindingset [ pai]
91+ pragma [ inline_late]
92+ predicate constantUpperBounded ( PointerArithmeticInstruction pai , int delta ) {
93+ semBounded ( getSemanticExpr ( pai .getRight ( ) ) , any ( SemZeroBound b ) , delta , true , _)
94+ }
95+
96+ bindingset [ pai, size]
97+ predicate pointerArithOverflow0Impl ( PointerArithmeticInstruction pai , int size , int bound , int delta ) {
98+ constantUpperBounded ( pai , bound ) and
9399 delta = bound - size and
94100 delta >= 0 and
95101 size != 0 and
96102 size != 1
97103}
98104
105+ predicate pointerArithOverflow0 ( PointerArithmeticInstruction pai , int delta ) {
106+ exists ( int size , int bound |
107+ arrayTypeHasSizes ( _, pai .getElementSize ( ) , size ) and
108+ pointerArithOverflow0Impl ( pai , size , bound , delta )
109+ )
110+ }
111+
99112module PointerArithmeticToDerefConfig implements DataFlow:: ConfigSig {
100- predicate isSource ( DataFlow:: Node source ) {
101- pointerArithOverflow0 ( source .asInstruction ( ) , _, _, _, _)
102- }
113+ predicate isSource ( DataFlow:: Node source ) { pointerArithOverflow0 ( source .asInstruction ( ) , _) }
103114
104115 predicate isBarrierIn ( DataFlow:: Node node ) { isSource ( node ) }
105116
@@ -110,30 +121,38 @@ module PointerArithmeticToDerefConfig implements DataFlow::ConfigSig {
110121
111122module PointerArithmeticToDerefFlow = DataFlow:: Global< PointerArithmeticToDerefConfig > ;
112123
113- predicate pointerArithOverflow (
114- PointerArithmeticInstruction pai , Variable v , int size , int bound , int delta
115- ) {
116- pointerArithOverflow0 ( pai , v , size , bound , delta ) and
124+ predicate pointerArithOverflow ( PointerArithmeticInstruction pai , int delta ) {
125+ pointerArithOverflow0 ( pai , delta ) and
117126 PointerArithmeticToDerefFlow:: flow ( DataFlow:: instructionNode ( pai ) , _)
118127}
119128
129+ bindingset [ v]
130+ predicate finalPointerArithOverflow ( Variable v , PointerArithmeticInstruction pai , int delta ) {
131+ exists ( int size |
132+ arrayTypeHasSizes ( pragma [ only_bind_out ] ( v .getUnspecifiedType ( ) ) , pai .getElementSize ( ) , size ) and
133+ pointerArithOverflow0Impl ( pai , size , _, delta )
134+ )
135+ }
136+
137+ predicate isSourceImpl ( DataFlow:: Node source , Variable v ) {
138+ (
139+ source .asInstruction ( ) .( FieldAddressInstruction ) .getField ( ) = v
140+ or
141+ source .asInstruction ( ) .( VariableAddressInstruction ) .getAstVariable ( ) = v
142+ ) and
143+ exists ( v .getUnspecifiedType ( ) .( ArrayType ) .getArraySize ( ) )
144+ }
145+
120146module ArrayAddressToDerefConfig implements DataFlow:: StateConfigSig {
121147 newtype FlowState =
122- additional TArray ( Variable v ) { pointerArithOverflow ( _ , v , _ , _ , _ ) } or
148+ additional TArray ( ) or
123149 additional TOverflowArithmetic ( PointerArithmeticInstruction pai ) {
124- pointerArithOverflow ( pai , _, _ , _ , _ )
150+ pointerArithOverflow ( pai , _)
125151 }
126152
127153 predicate isSource ( DataFlow:: Node source , FlowState state ) {
128- exists ( Variable v |
129- (
130- source .asInstruction ( ) .( FieldAddressInstruction ) .getField ( ) = v
131- or
132- source .asInstruction ( ) .( VariableAddressInstruction ) .getAstVariable ( ) = v
133- ) and
134- exists ( v .getUnspecifiedType ( ) .( ArrayType ) .getArraySize ( ) ) and
135- state = TArray ( v )
136- )
154+ isSourceImpl ( source , _) and
155+ state = TArray ( )
137156 }
138157
139158 predicate isSink ( DataFlow:: Node sink , FlowState state ) {
@@ -152,12 +171,12 @@ module ArrayAddressToDerefConfig implements DataFlow::StateConfigSig {
152171 predicate isAdditionalFlowStep (
153172 DataFlow:: Node node1 , FlowState state1 , DataFlow:: Node node2 , FlowState state2
154173 ) {
155- exists ( PointerArithmeticInstruction pai , Variable v |
156- state1 = TArray ( v ) and
174+ exists ( PointerArithmeticInstruction pai |
175+ state1 = TArray ( ) and
157176 state2 = TOverflowArithmetic ( pai ) and
158177 pai .getLeft ( ) = node1 .asInstruction ( ) and
159178 node2 .asInstruction ( ) = pai and
160- pointerArithOverflow ( pai , v , _ , _ , _)
179+ pointerArithOverflow ( pai , _)
161180 )
162181 }
163182}
@@ -168,11 +187,11 @@ from
168187 Variable v , ArrayAddressToDerefFlow:: PathNode source , PointerArithmeticInstruction pai ,
169188 ArrayAddressToDerefFlow:: PathNode sink , Instruction deref , string operation , int delta
170189where
171- ArrayAddressToDerefFlow:: flowPath ( source , sink ) and
190+ ArrayAddressToDerefFlow:: flowPath ( pragma [ only_bind_into ] ( source ) , pragma [ only_bind_into ] ( sink ) ) and
172191 isInvalidPointerDerefSink2 ( sink .getNode ( ) , deref , operation ) and
173- source .getState ( ) = ArrayAddressToDerefConfig:: TArray ( v ) and
174- sink . getState ( ) = ArrayAddressToDerefConfig :: TOverflowArithmetic ( pai ) and
175- pointerArithOverflow ( pai , v , _ , _ , delta )
192+ pragma [ only_bind_out ] ( sink .getState ( ) ) = ArrayAddressToDerefConfig:: TOverflowArithmetic ( pai ) and
193+ isSourceImpl ( source . getNode ( ) , v ) and
194+ finalPointerArithOverflow ( v , pai , delta )
176195select pai , source , sink ,
177196 "This pointer arithmetic may have an off-by-" + ( delta + 1 ) +
178197 " error allowing it to overrun $@ at this $@." , v , v .getName ( ) , deref , operation
0 commit comments