@@ -25,16 +25,23 @@ Instruction getABoundIn(SemBound b, IRFunction func) {
2525/**
2626 * Holds if `i <= b + delta`.
2727 */
28- bindingset [ i]
29- pragma [ inline_late]
30- predicate bounded ( Instruction i , Instruction b , int delta ) {
28+ pragma [ inline]
29+ predicate boundedImpl ( Instruction i , Instruction b , int delta ) {
3130 exists ( SemBound bound , IRFunction func |
3231 semBounded ( getSemanticExpr ( i ) , bound , delta , true , _) and
3332 b = getABoundIn ( bound , func ) and
34- i .getEnclosingIRFunction ( ) = func
33+ pragma [ only_bind_out ] ( i .getEnclosingIRFunction ( ) ) = func
3534 )
3635}
3736
37+ bindingset [ i]
38+ pragma [ inline_late]
39+ predicate bounded1 ( Instruction i , Instruction b , int delta ) { boundedImpl ( i , b , delta ) }
40+
41+ bindingset [ b]
42+ pragma [ inline_late]
43+ predicate bounded2 ( Instruction i , Instruction b , int delta ) { boundedImpl ( i , b , delta ) }
44+
3845module FieldAddressToPointerArithmeticConfig implements DataFlow:: ConfigSig {
3946 predicate isSource ( DataFlow:: Node source ) { isFieldAddressSource ( _, source ) }
4047
@@ -50,23 +57,39 @@ predicate isFieldAddressSource(Field f, DataFlow::Node source) {
5057 source .asInstruction ( ) .( FieldAddressInstruction ) .getField ( ) = f
5158}
5259
60+ bindingset [ delta]
61+ predicate isInvalidPointerDerefSinkImpl (
62+ int delta , Instruction i , AddressOperand addr , string operation
63+ ) {
64+ delta >= 0 and
65+ i .getAnOperand ( ) = addr and
66+ (
67+ i instanceof StoreInstruction and
68+ operation = "write"
69+ or
70+ i instanceof LoadInstruction and
71+ operation = "read"
72+ )
73+ }
74+
5375/**
5476 * Holds if `sink` is a sink for `InvalidPointerToDerefConf` and `i` is a `StoreInstruction` that
5577 * writes to an address that non-strictly upper-bounds `sink`, or `i` is a `LoadInstruction` that
5678 * reads from an address that non-strictly upper-bounds `sink`.
5779 */
5880pragma [ inline]
59- predicate isInvalidPointerDerefSink ( DataFlow:: Node sink , Instruction i , string operation ) {
81+ predicate isInvalidPointerDerefSink1 ( DataFlow:: Node sink , Instruction i , string operation ) {
6082 exists ( AddressOperand addr , int delta |
61- bounded ( addr .getDef ( ) , sink .asInstruction ( ) , delta ) and
62- delta >= 0 and
63- i .getAnOperand ( ) = addr
64- |
65- i instanceof StoreInstruction and
66- operation = "write"
67- or
68- i instanceof LoadInstruction and
69- operation = "read"
83+ bounded1 ( addr .getDef ( ) , sink .asInstruction ( ) , delta ) and
84+ isInvalidPointerDerefSinkImpl ( delta , i , addr , operation )
85+ )
86+ }
87+
88+ pragma [ inline]
89+ predicate isInvalidPointerDerefSink2 ( DataFlow:: Node sink , Instruction i , string operation ) {
90+ exists ( AddressOperand addr , int delta |
91+ bounded2 ( addr .getDef ( ) , sink .asInstruction ( ) , delta ) and
92+ isInvalidPointerDerefSinkImpl ( delta , i , addr , operation )
7093 )
7194}
7295
@@ -90,7 +113,7 @@ module PointerArithmeticToDerefConfig implements DataFlow::ConfigSig {
90113 }
91114
92115 pragma [ inline]
93- predicate isSink ( DataFlow:: Node sink ) { isInvalidPointerDerefSink ( sink , _, _) }
116+ predicate isSink ( DataFlow:: Node sink ) { isInvalidPointerDerefSink1 ( sink , _, _) }
94117}
95118
96119module PointerArithmeticToDerefFlow = DataFlow:: Global< PointerArithmeticToDerefConfig > ;
100123 PointerArithmeticToDerefFlow:: PathNode sink , Instruction deref , string operation , int delta
101124where
102125 PointerArithmeticToDerefFlow:: flowPath ( source , sink ) and
103- isInvalidPointerDerefSink ( sink .getNode ( ) , deref , operation ) and
126+ isInvalidPointerDerefSink2 ( sink .getNode ( ) , deref , operation ) and
104127 isConstantSizeOverflowSource ( f , source .getNode ( ) .asInstruction ( ) , delta )
105128select source , source , sink ,
106129 "This pointer arithmetic may have an off-by-" + ( delta + 1 ) +
0 commit comments