Skip to content

Commit 8e8a324

Browse files
authored
Add files via upload
1 parent 5709365 commit 8e8a324

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
...
2+
fp = fopen("/tmp/name.tmp","w"); // BAD
3+
...
4+
char filename = tmpnam(NULL);
5+
fp = fopen(filename,"w"); // BAD
6+
...
7+
8+
strcat (filename, "/tmp/name.XXXXXX");
9+
fd = mkstemp(filename);
10+
if ( fd < 0 ) {
11+
return error;
12+
}
13+
fp = fdopen(fd,"w") // GOOD
14+
...
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Working with a file, without checking its existence and its rights, as well as working with names that can be predicted, may not be safe. Requires the attention of developers.</p>
7+
8+
</recommendation>
9+
<example>
10+
<p>The following example demonstrates erroneous and corrected work with file.</p>
11+
<sample src="InsecureTemporaryFile.cpp" />
12+
13+
</example>
14+
<references>
15+
16+
<li>
17+
CERT C Coding Standard:
18+
<a href="https://wiki.sei.cmu.edu/confluence/display/c/CON33-C.+Avoid+race+conditions+when+using+library+functions">CON33-C. Avoid race conditions when using library functions</a>.
19+
</li>
20+
21+
</references>
22+
</qhelp>
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/**
2+
* @name Find insecure work with the file name.
3+
* @description The file can be used to influence the correct operation of the program.
4+
* @kind problem
5+
* @id cpp/insecure-work-with-file-name
6+
* @problem.severity warning
7+
* @precision medium
8+
* @tags correctness
9+
* security
10+
* external/cwe/cwe-377
11+
*/
12+
13+
import cpp
14+
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
15+
16+
/** Holds for a function `f` that has an argument at index `apos` used to read the file. */
17+
predicate numberArgumentRead(Function f, int apos) {
18+
f.hasGlobalOrStdName("fgets") and apos = 2
19+
or
20+
f.hasGlobalOrStdName("fread") and apos = 3
21+
or
22+
f.hasGlobalOrStdName("read") and apos = 0
23+
or
24+
f.hasGlobalOrStdName("fscanf") and apos = 0
25+
}
26+
27+
/** Holds for a function `f` that has an argument at index `apos` used to write to file */
28+
predicate numberArgumentWrite(Function f, int apos) {
29+
f.hasGlobalOrStdName("fprintf") and apos = 0
30+
or
31+
f.hasGlobalOrStdName("fputs") and apos = 1
32+
or
33+
f.hasGlobalOrStdName("write") and apos = 0
34+
or
35+
f.hasGlobalOrStdName("fwrite") and apos = 3
36+
or
37+
f.hasGlobalOrStdName("fflush") and apos = 0
38+
}
39+
40+
from FunctionCall fc, string msg
41+
where
42+
(
43+
fc.getTarget().hasGlobalOrStdName("tmpnam") or
44+
fc.getTarget().hasGlobalOrStdName("tmpnam_s") or
45+
fc.getTarget().hasGlobalOrStdName("tmpnam_r")
46+
) and
47+
not exists(FunctionCall fctmp |
48+
fctmp.getTarget().hasGlobalOrStdName("mktemp") or
49+
fctmp.getTarget().hasGlobalOrStdName("mkstemp") or
50+
fctmp.getTarget().hasGlobalOrStdName("mkstemps") or
51+
fctmp.getTarget().hasGlobalOrStdName("mkdtemp")
52+
) and
53+
msg =
54+
"Finding the name of a file that does not exist does not mean that it will not be exist at the next operation."
55+
or
56+
(
57+
fc.getTarget().hasGlobalOrStdName("fopen") or
58+
fc.getTarget().hasGlobalOrStdName("open")
59+
) and
60+
fc.getNumberOfArguments() = 2 and
61+
exists(FunctionCall fctmp, int i |
62+
numberArgumentWrite(fctmp.getTarget(), i) and
63+
globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i))
64+
) and
65+
not exists(FunctionCall fctmp, int i |
66+
numberArgumentRead(fctmp.getTarget(), i) and
67+
globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i))
68+
) and
69+
exists(FunctionCall fctmp |
70+
(
71+
fctmp.getTarget().hasGlobalOrStdName("strcat") or
72+
fctmp.getTarget().hasGlobalOrStdName("strcpy")
73+
) and
74+
globalValueNumber(fc.getArgument(0)) = globalValueNumber(fctmp.getAnArgument())
75+
or
76+
fctmp.getTarget().hasGlobalOrStdName("getenv") and
77+
globalValueNumber(fc.getArgument(0)) = globalValueNumber(fctmp)
78+
or
79+
(
80+
fctmp.getTarget().hasGlobalOrStdName("asprintf") or
81+
fctmp.getTarget().hasGlobalOrStdName("vasprintf") or
82+
fctmp.getTarget().hasGlobalOrStdName("xasprintf") or
83+
fctmp.getTarget().hasGlobalOrStdName("xvasprintf ")
84+
) and
85+
exists(Variable vrtmp |
86+
vrtmp = fc.getArgument(0).(VariableAccess).getTarget() and
87+
vrtmp = fctmp.getArgument(0).(AddressOfExpr).getAddressable().(Variable) and
88+
not vrtmp instanceof Field
89+
)
90+
) and
91+
not exists(FunctionCall fctmp |
92+
fctmp.getTarget().hasGlobalOrStdName("umask") or
93+
fctmp.getTarget().hasGlobalOrStdName("fchmod") or
94+
fctmp.getTarget().hasGlobalOrStdName("chmod")
95+
) and
96+
msg =
97+
"Сreating a file for writing without evaluating its existence and setting permissions can be unsafe."
98+
select fc, msg

0 commit comments

Comments
 (0)