|
13 | 13 | import cpp |
14 | 14 | import semmle.code.cpp.valuenumbering.GlobalValueNumbering |
15 | 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 | 16 | from FunctionCall fc, string msg |
41 | 17 | where |
42 | 18 | // search for functions for generating a name, without a guarantee of the absence of a file during the period of work with it. |
|
59 | 35 | ) and |
60 | 36 | msg = |
61 | 37 | "Finding the name of a file that does not exist does not mean that it will not be exist at the next operation." |
62 | | - or |
63 | | - // finding places to work with a file without setting permissions, but with predictable names. |
64 | | - ( |
65 | | - fc.getTarget().hasGlobalOrStdName("fopen") or |
66 | | - fc.getTarget().hasGlobalOrStdName("open") |
67 | | - ) and |
68 | | - fc.getNumberOfArguments() = 2 and |
69 | | - exists(FunctionCall fctmp, int i | |
70 | | - numberArgumentWrite(fctmp.getTarget(), i) and |
71 | | - globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i)) |
72 | | - ) and |
73 | | - not exists(FunctionCall fctmp, int i | |
74 | | - numberArgumentRead(fctmp.getTarget(), i) and |
75 | | - globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i)) |
76 | | - ) and |
77 | | - exists(FunctionCall fctmp | |
78 | | - ( |
79 | | - fctmp.getTarget().hasGlobalOrStdName("strcat") or |
80 | | - fctmp.getTarget().hasGlobalOrStdName("strcpy") |
81 | | - ) and |
82 | | - globalValueNumber(fc.getArgument(0)) = globalValueNumber(fctmp.getAnArgument()) |
83 | | - or |
84 | | - fctmp.getTarget().hasGlobalOrStdName("getenv") and |
85 | | - globalValueNumber(fc.getArgument(0)) = globalValueNumber(fctmp) |
86 | | - or |
87 | | - ( |
88 | | - fctmp.getTarget().hasGlobalOrStdName("asprintf") or |
89 | | - fctmp.getTarget().hasGlobalOrStdName("vasprintf") or |
90 | | - fctmp.getTarget().hasGlobalOrStdName("xasprintf") or |
91 | | - fctmp.getTarget().hasGlobalOrStdName("xvasprintf ") |
92 | | - ) and |
93 | | - exists(Variable vrtmp | |
94 | | - vrtmp = fc.getArgument(0).(VariableAccess).getTarget() and |
95 | | - vrtmp = fctmp.getArgument(0).(AddressOfExpr).getAddressable() and |
96 | | - not vrtmp instanceof Field |
97 | | - ) |
98 | | - ) and |
99 | | - not exists(FunctionCall fctmp | |
100 | | - ( |
101 | | - fctmp.getTarget().hasGlobalOrStdName("umask") or |
102 | | - fctmp.getTarget().hasGlobalOrStdName("fchmod") or |
103 | | - fctmp.getTarget().hasGlobalOrStdName("chmod") |
104 | | - ) and |
105 | | - ( |
106 | | - fc.getBasicBlock().getASuccessor*() = fctmp.getBasicBlock() or |
107 | | - fctmp.getBasicBlock().getASuccessor*() = fc.getBasicBlock() |
108 | | - ) |
109 | | - ) and |
110 | | - msg = |
111 | | - "Creating a file for writing without evaluating its existence and setting permissions can be unsafe." |
112 | 38 | select fc, msg |
0 commit comments