|
15 | 15 | import cpp |
16 | 16 | import codingstandards.cpp.misra |
17 | 17 | import semmle.code.cpp.dataflow.new.DataFlow |
| 18 | +import semmle.code.cpp.security.BufferAccess |
| 19 | + |
| 20 | +class ArrayDeclaration extends VariableDeclarationEntry { |
| 21 | + int length; |
| 22 | + |
| 23 | + ArrayDeclaration() { this.getType().getUnderlyingType().(ArrayType).getArraySize() = length } |
| 24 | + |
| 25 | + /** |
| 26 | + * Gets the declared length of this array. |
| 27 | + */ |
| 28 | + int getLength() { result = length } |
| 29 | +} |
| 30 | + |
| 31 | +newtype TArrayAllocation = |
| 32 | + TStackAllocation(ArrayDeclaration arrayDecl) or |
| 33 | + TDynamicAllocation(AllocationFunction alloc) |
| 34 | + |
| 35 | +class ArrayAllocation extends TArrayAllocation { |
| 36 | + ArrayDeclaration asStackAllocation() { this = TStackAllocation(result) } |
| 37 | + |
| 38 | + AllocationFunction asDynamicAllocation() { this = TDynamicAllocation(result) } |
| 39 | + |
| 40 | + string toString() { |
| 41 | + result = this.asStackAllocation().toString() or |
| 42 | + result = this.asDynamicAllocation().toString() |
| 43 | + } |
| 44 | + |
| 45 | + int getLength() { |
| 46 | + result = this.asStackAllocation().getLength() or |
| 47 | + none() // TODO: this.asDynamicAllocation() |
| 48 | + } |
| 49 | +} |
18 | 50 |
|
19 | 51 | module TrackArrayConfig implements DataFlow::ConfigSig { |
20 | 52 | predicate isSource(DataFlow::Node node) { |
21 | | - /* 1. Declaring an array-type variable */ |
22 | | - none() |
| 53 | + /* 1. Declaring / Initializing an array-type variable */ |
| 54 | + exists(ArrayDeclaration arrayDecl | |
| 55 | + node.asExpr() = arrayDecl.getVariable().getInitializer().getExpr() |
| 56 | + ) |
23 | 57 | or |
24 | 58 | /* 2. Allocating dynamic memory as an array */ |
25 | | - none() |
| 59 | + none() // TODO |
26 | 60 | } |
27 | 61 |
|
28 | 62 | predicate isSink(DataFlow::Node node) { |
29 | 63 | /* 1. Pointer arithmetic */ |
30 | | - none() |
| 64 | + exists(PointerArithmeticOperation pointerArithmetic | |
| 65 | + node.asIndirectExpr() = pointerArithmetic.getAnOperand() |
| 66 | + ) |
31 | 67 | or |
32 | 68 | /* 2. Array access */ |
33 | | - none() |
| 69 | + node.asExpr() instanceof ArrayExprBA |
34 | 70 | } |
35 | 71 | } |
36 | 72 |
|
37 | 73 | module TrackArray = DataFlow::Global<TrackArrayConfig>; |
38 | 74 |
|
| 75 | +private predicate arrayDeclarationAndAccess( |
| 76 | + DataFlow::Node arrayDeclaration, DataFlow::Node arrayAccess |
| 77 | +) { |
| 78 | + TrackArray::flow(arrayDeclaration, arrayAccess) |
| 79 | +} |
| 80 | + |
| 81 | +private predicate arrayIndexExceedsOutOfBounds( |
| 82 | + DataFlow::Node arrayDeclaration, DataFlow::Node arrayAccess |
| 83 | +) { |
| 84 | + arrayDeclarationAndAccess(arrayDeclaration, arrayAccess) and |
| 85 | + // exists(int declaredLength | |
| 86 | + // declaredLength = arrayDeclaration |
| 87 | + // ) |
| 88 | + any() // TODO |
| 89 | +} |
| 90 | + |
39 | 91 | from Expr expr |
40 | 92 | where |
41 | 93 | not isExcluded(expr, Memory1Package::pointerArithmeticFormsAnInvalidPointerQuery()) and |
|
0 commit comments