forked from github/codeql-coding-standards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFileOpenForReadAndWriteOnDifferentStreams.ql
More file actions
69 lines (62 loc) · 2.08 KB
/
FileOpenForReadAndWriteOnDifferentStreams.ql
File metadata and controls
69 lines (62 loc) · 2.08 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
/**
* @id c/misra/file-open-for-read-and-write-on-different-streams
* @name RULE-22-3: The same file shall not be open for read and write access at the same time on different streams
* @description Accessing the same file for read and write from different streams is undefined
* behavior.
* @kind problem
* @precision high
* @problem.severity error
* @tags external/misra/id/rule-22-3
* correctness
* external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
import codingstandards.cpp.standardlibrary.FileAccess
import semmle.code.cpp.dataflow.new.DataFlow
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.controlflow.SubBasicBlocks
/**
* Models calls to `fopen` with different read/write modes
*/
class FOpenSBB extends SubBasicBlockCutNode {
FOpenSBB() {
this instanceof FOpenCall or
this instanceof FileCloseFunctionCall
}
}
SubBasicBlock followsOpen(FOpenCall fopen) {
result = fopen
or
exists(SubBasicBlock mid |
result = mid.getASuccessor() and
mid = followsOpen(fopen) and
// stop recursion when the first stream is closed
not DataFlow::localExprFlow(fopen, result.(FileCloseFunctionCall).getFileExpr())
)
}
class MatchedFOpenCall extends FOpenCall {
FOpenCall pair;
MatchedFOpenCall() {
not pair = this and
pair.getEnclosingFunction() = this.getEnclosingFunction() and
this = followsOpen(pair)
}
FOpenCall getMatch() { result = pair }
}
from MatchedFOpenCall fst, FOpenCall snd
where
not isExcluded(fst, IO3Package::fileOpenForReadAndWriteOnDifferentStreamsQuery()) and
// must be opening the same filename
snd = fst.getMatch() and
globalValueNumber(fst.getFilenameExpr()) = globalValueNumber(snd.getFilenameExpr()) and
(
// different open mode
fst.isReadMode() and snd.isWriteMode()
or
fst.isWriteMode() and snd.isReadMode()
)
select fst,
"The same file was already opened $@. Files should not be read and written at the same time using different streams.",
snd, "here"