forked from github/codeql-coding-standards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCallPOSIXOpenWithCorrectArgumentCount.ql
More file actions
70 lines (64 loc) · 2.43 KB
/
CallPOSIXOpenWithCorrectArgumentCount.ql
File metadata and controls
70 lines (64 loc) · 2.43 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
/**
* @id c/cert/call-posix-open-with-correct-argument-count
* @name EXP37-C: Pass the correct number of arguments to the POSIX open function
* @description A third argument should be passed to the POSIX function open() when and only when
* creating a new file.
* @kind problem
* @precision high
* @problem.severity error
* @tags external/cert/id/exp37-c
* correctness
* security
* external/cert/obligation/rule
*/
import cpp
import codingstandards.c.cert
import semmle.code.cpp.commons.unix.Constants
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
int o_creat_val() {
result = any(MacroInvocation ma | ma.getMacroName() = "O_CREAT" | ma.getExpr().getValue().toInt())
or
result = o_creat()
}
/**
* A function call to POSIX open()
*/
class POSIXOpenFunctionCall extends FunctionCall {
POSIXOpenFunctionCall() { this.getTarget().getQualifiedName() = "open" }
/**
* Holds if reasonable bounds exist for the value of the 'flags' argument of the call.
* This predicate will never hold for cases such as wrapper functions
* which pass a parameter to the open() 'flags' argument.
*/
predicate hasFlagsArgBounds() { lowerBound(this.getArgument(1)) >= 0 }
/**
* Holds if the 'flags' argument contains the O_CREAT flag.
* Because this predicate uses the SimpleRangeAnalysis library, it only
* analyzes the bounds of 'flag' arguments which can be deduced locally.
*/
predicate isOpenCreateCall() {
hasFlagsArgBounds() and
upperBound(this.getArgument(1)).(int).bitAnd(o_creat_val()) != 0
}
}
from POSIXOpenFunctionCall call, string message
where
not isExcluded(call, ExpressionsPackage::callPOSIXOpenWithCorrectArgumentCountQuery()) and
// include only analyzable flag arguments which have values that can be determined locally
call.hasFlagsArgBounds() and
// differentiate between two variants:
// 1) a call to open() with the O_CREAT flag set, which should pass three arguments
// 2) a call to open without the O_CREAT flag set, which should pass two arguments
if call.isOpenCreateCall()
then (
call.getNumberOfArguments() != 3 and
message =
"Call to " + call.getTarget().getName() +
" with O_CREAT flag does not pass exactly three arguments."
) else (
call.getNumberOfArguments() != 2 and
message =
"Call to " + call.getTarget().getName() +
" without O_CREAT flag does not pass exactly two arguments."
)
select call, message