forked from github/codeql-coding-standards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathErrnoNotSetToZero.ql
More file actions
52 lines (49 loc) · 1.69 KB
/
ErrnoNotSetToZero.ql
File metadata and controls
52 lines (49 loc) · 1.69 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
/**
* @id c/cert/errno-not-set-to-zero
* @name ERR30-C: Errno is not set to zero prior to an errno-setting call
* @description Set errno to zero prior to each call to an errno-setting function. Failing to do so
* might end in spurious errno values.
* @kind problem
* @precision high
* @problem.severity error
* @tags external/cert/id/err30-c
* correctness
* external/cert/obligation/rule
* external/cert/priority/p8
* external/cert/level/l2
*/
import cpp
import codingstandards.c.cert
import codingstandards.c.Errno
/**
* CFG nodes preceding a `ErrnoSettingFunctionCall`
*/
ControlFlowNode notZeroedPriorToErrnoSet(InBandErrnoSettingFunctionCall fc) {
result = fc
or
exists(ControlFlowNode mid |
result = mid.getAPredecessor() and
mid = notZeroedPriorToErrnoSet(fc) and
// stop recursion when `errno` is set to zero
not result instanceof ErrnoZeroed and
not result = any(ErrnoGuard g).getZeroedSuccessor()
)
}
from InBandErrnoSettingFunctionCall fc, ControlFlowNode cause
where
not isExcluded(cause, Contracts4Package::errnoNotSetToZeroQuery()) and
cause = notZeroedPriorToErrnoSet(fc) and
(
// `errno` is not reset anywhere in the function
cause = fc.getEnclosingFunction().getBlock()
or
// `errno` is not reset after a call to an errno-setting function
cause = any(InBandErrnoSettingFunctionCall ec | ec != fc)
or
// `errno` is not reset after a call to a function
cause = any(FunctionCall fc2 | fc2 != fc)
or
// `errno` value is known to be != 0
cause = any(ErrnoGuard g).getNonZeroedSuccessor()
)
select fc, "The value of `errno` may be different than `0` when this function is called."