forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNtohlArrayNoBound.qll
More file actions
148 lines (111 loc) · 4.38 KB
/
NtohlArrayNoBound.qll
File metadata and controls
148 lines (111 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import cpp
import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.controlflow.Guards
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/**
* An access (read or write) to a buffer, provided as a pair of
* a pointer to the buffer and the length of data to be read or written.
* Extend this class to support different kinds of buffer access.
*/
abstract class BufferAccess extends Locatable {
/** Gets the pointer to the buffer being accessed. */
abstract Expr getPointer();
/** Gets the length of the data being read or written by this buffer access. */
abstract Expr getAccessedLength();
}
/**
* A buffer access through an array expression.
*/
class ArrayBufferAccess extends BufferAccess, ArrayExpr {
override Expr getPointer() { result = this.getArrayBase() }
override Expr getAccessedLength() { result = this.getArrayOffset() }
}
/**
* A buffer access through an overloaded array expression.
*/
class OverloadedArrayBufferAccess extends BufferAccess, OverloadedArrayExpr {
override Expr getPointer() { result = this.getQualifier() }
override Expr getAccessedLength() { result = this.getAnArgument() }
}
/**
* A buffer access through pointer arithmetic.
*/
class PointerArithmeticAccess extends BufferAccess, Expr {
PointerArithmeticOperation p;
PointerArithmeticAccess() {
this = p and
p.getAnOperand().getType().getUnspecifiedType() instanceof IntegralType and
not p.getParent() instanceof ComparisonOperation
}
override Expr getPointer() {
result = p.getAnOperand() and
result.getType().getUnspecifiedType() instanceof PointerType
}
override Expr getAccessedLength() {
result = p.getAnOperand() and
result.getType().getUnspecifiedType() instanceof IntegralType
}
}
/**
* A pair of buffer accesses through a call to memcpy.
*/
class MemCpy extends BufferAccess, FunctionCall {
MemCpy() { this.getTarget().hasName("memcpy") }
override Expr getPointer() {
result = this.getArgument(0) or
result = this.getArgument(1)
}
override Expr getAccessedLength() { result = this.getArgument(2) }
}
class StrncpySizeExpr extends BufferAccess, FunctionCall {
StrncpySizeExpr() { this.getTarget().hasName("strncpy") }
override Expr getPointer() {
result = this.getArgument(0) or
result = this.getArgument(1)
}
override Expr getAccessedLength() { result = this.getArgument(2) }
}
class RecvSizeExpr extends BufferAccess, FunctionCall {
RecvSizeExpr() { this.getTarget().hasName("recv") }
override Expr getPointer() { result = this.getArgument(1) }
override Expr getAccessedLength() { result = this.getArgument(2) }
}
class SendSizeExpr extends BufferAccess, FunctionCall {
SendSizeExpr() { this.getTarget().hasName("send") }
override Expr getPointer() { result = this.getArgument(1) }
override Expr getAccessedLength() { result = this.getArgument(2) }
}
class SnprintfSizeExpr extends BufferAccess, FunctionCall {
SnprintfSizeExpr() { this.getTarget().hasName("snprintf") }
override Expr getPointer() { result = this.getArgument(0) }
override Expr getAccessedLength() { result = this.getArgument(1) }
}
class MemcmpSizeExpr extends BufferAccess, FunctionCall {
MemcmpSizeExpr() { this.getTarget().hasName("memcmp") }
override Expr getPointer() {
result = this.getArgument(0) or
result = this.getArgument(1)
}
override Expr getAccessedLength() { result = this.getArgument(2) }
}
class MallocSizeExpr extends BufferAccess, FunctionCall {
MallocSizeExpr() { this.getTarget().hasName("malloc") }
override Expr getPointer() { none() }
override Expr getAccessedLength() { result = this.getArgument(0) }
}
class NetworkFunctionCall extends FunctionCall {
NetworkFunctionCall() { this.getTarget().hasName(["ntohd", "ntohf", "ntohl", "ntohll", "ntohs"]) }
}
private module NetworkToBufferSizeConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node.asExpr() instanceof NetworkFunctionCall }
predicate isSink(DataFlow::Node node) { node.asExpr() = any(BufferAccess ba).getAccessedLength() }
predicate isBarrier(DataFlow::Node node) {
exists(GuardCondition gc, GVN gvn |
gc.getAChild*() = gvn.getAnExpr() and
globalValueNumber(node.asExpr()) = gvn and
gc.controls(node.asExpr().getBasicBlock(), _)
)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
module NetworkToBufferSizeFlow = DataFlow::Global<NetworkToBufferSizeConfig>;