-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathOverflowCalculated.ql
More file actions
78 lines (74 loc) · 3.05 KB
/
OverflowCalculated.ql
File metadata and controls
78 lines (74 loc) · 3.05 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
/**
* @name Buffer overflow from insufficient space or incorrect size calculation
* @description A buffer allocated using 'malloc' may not have enough space for a string being copied into it, or wide character functions may receive incorrect size parameters causing buffer overrun. Make sure that buffers contain enough room for strings (including zero terminator) and that size parameters are correctly calculated.
* @kind problem
* @precision medium
* @id cpp/overflow-calculated
* @problem.severity warning
* @security-severity 9.8
* @tags reliability
* security
* external/cwe/cwe-131
* external/cwe/cwe-120
*/
import cpp
import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.models.interfaces.Allocation
predicate spaceProblem(FunctionCall append, string msg) {
exists(
AllocationExpr malloc, StrlenCall strlen, AddExpr add, FunctionCall insert, Variable buffer
|
add.getAChild() = strlen and
exists(add.getAChild().getValue()) and
DataFlow::localExprFlow(add, malloc.getSizeExpr()) and
buffer.getAnAccess() = strlen.getStringExpr() and
(
insert.getTarget().hasGlobalOrStdName("strcpy") or
insert.getTarget().hasGlobalOrStdName("strncpy")
) and
(
append.getTarget().hasGlobalOrStdName("strcat") or
append.getTarget().hasGlobalOrStdName("strncat")
) and
malloc.getASuccessor+() = insert and
insert.getArgument(1) = buffer.getAnAccess() and
insert.getASuccessor+() = append and
msg =
"This buffer only contains enough room for '" + buffer.getName() + "' (copied on line " +
insert.getLocation().getStartLine().toString() + ")"
)
}
predicate wideCharSizeofProblem(FunctionCall call, string msg) {
exists(
Variable buffer, SizeofExprOperator sizeofOp
|
// Function call is to wcsftime
call.getTarget().hasGlobalOrStdName("wcsftime") and
// Second argument (count parameter) is a sizeof operation
call.getArgument(1) = sizeofOp and
// The sizeof is applied to a buffer variable
sizeofOp.getExprOperand() = buffer.getAnAccess() and
(
// Case 1: Array of wchar_t - sizeof gives bytes instead of element count
exists(ArrayType arrayType |
arrayType = buffer.getType() and
arrayType.getBaseType().hasName("wchar_t") and
msg =
"Using sizeof(" + buffer.getName() + ") passes byte count instead of wchar_t element count to wcsftime. " +
"Use sizeof(" + buffer.getName() + ")/sizeof(wchar_t) or array length instead."
)
or
// Case 2: Pointer to wchar_t - sizeof gives pointer size, which is completely wrong
exists(PointerType ptrType |
ptrType = buffer.getType() and
ptrType.getBaseType().hasName("wchar_t") and
msg =
"Using sizeof(" + buffer.getName() + ") passes pointer size instead of buffer size to wcsftime. " +
"Pass the actual element count or use a length variable instead."
)
)
)
}
from Expr problem, string msg
where spaceProblem(problem, msg) or wideCharSizeofProblem(problem, msg)
select problem, msg