Skip to content

Commit 344e380

Browse files
authored
Merge pull request #6949 from ihsinme/ihsinme-patch-073
CPP: Add query for CWE-266 Incorrect Privilege Assignment
2 parents a2c1995 + 0f0bd34 commit 344e380

File tree

6 files changed

+178
-0
lines changed

6 files changed

+178
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
...
2+
umask(0); // BAD
3+
...
4+
maskOut = S_IRWXG | S_IRWXO;
5+
umask(maskOut); // GOOD
6+
...
7+
fchmod(fileno(fp), 0555 - maskOut); // BAD
8+
...
9+
fchmod(fileno(fp), 0555 & ~maskOut); // GOOD
10+
...
11+
umask(0666);
12+
chmod(pathname, 0666); // BAD
13+
...
14+
umask(0022);
15+
chmod(pathname, 0666); // GOOD
16+
...
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Finding for function calls that set file permissions that may have errors in use. Incorrect arithmetic for calculating the resolution mask, using the same mask in opposite functions, using a mask that is too wide.</p>
7+
8+
</overview>
9+
10+
<example>
11+
<p>The following example demonstrates erroneous and fixed ways to use functions.</p>
12+
<sample src="IncorrectPrivilegeAssignment.cpp" />
13+
14+
</example>
15+
<references>
16+
17+
<li>
18+
CERT C Coding Standard:
19+
<a href="https://wiki.sei.cmu.edu/confluence/display/c/FIO06-C.+Create+files+with+appropriate+access+permissions">FIO06-C. Create files with appropriate access permissions</a>.
20+
</li>
21+
22+
</references>
23+
</qhelp>
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
* @name Find the wrong use of the umask function.
3+
* @description Incorrectly evaluated argument to the umask function may have security implications.
4+
* @kind problem
5+
* @id cpp/wrong-use-of-the-umask
6+
* @problem.severity warning
7+
* @precision medium
8+
* @tags correctness
9+
* maintainability
10+
* security
11+
* external/cwe/cwe-266
12+
* external/cwe/cwe-264
13+
* external/cwe/cwe-200
14+
* external/cwe/cwe-560
15+
* external/cwe/cwe-687
16+
*/
17+
18+
import cpp
19+
import semmle.code.cpp.exprs.BitwiseOperation
20+
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
21+
22+
/**
23+
* An expression that is either a `BinaryArithmeticOperation` or the result of one or more `BinaryBitwiseOperation`s on a `BinaryArithmeticOperation`. For example `1 | (2 + 3)`.
24+
*/
25+
class ContainsArithmetic extends Expr {
26+
ContainsArithmetic() {
27+
this instanceof BinaryArithmeticOperation
28+
or
29+
// recursive search into `Operation`s
30+
this.(BinaryBitwiseOperation).getAnOperand() instanceof ContainsArithmetic
31+
}
32+
}
33+
34+
/** Holds for a function `f` that has an argument at index `apos` used to set file permissions. */
35+
predicate numberArgumentModFunctions(Function f, int apos) {
36+
f.hasGlobalOrStdName("umask") and apos = 0
37+
or
38+
f.hasGlobalOrStdName("fchmod") and apos = 1
39+
or
40+
f.hasGlobalOrStdName("chmod") and apos = 1
41+
}
42+
43+
from FunctionCall fc, string msg, FunctionCall fcsnd
44+
where
45+
fc.getTarget().hasGlobalOrStdName("umask") and
46+
fc.getArgument(0).getValue() = "0" and
47+
not exists(FunctionCall fctmp |
48+
fctmp.getTarget().hasGlobalOrStdName("umask") and
49+
not fctmp.getArgument(0).getValue() = "0"
50+
) and
51+
exists(FunctionCall fctmp |
52+
(
53+
fctmp.getTarget().hasGlobalOrStdName("fopen") or
54+
fctmp.getTarget().hasGlobalOrStdName("open")
55+
) and
56+
not fctmp.getArgument(1).getValue().matches("r%") and
57+
fctmp.getNumberOfArguments() = 2 and
58+
not fctmp.getArgument(0).getValue() = "/dev/null" and
59+
fcsnd = fctmp
60+
) and
61+
not exists(FunctionCall fctmp |
62+
fctmp.getTarget().hasGlobalOrStdName("chmod") or
63+
fctmp.getTarget().hasGlobalOrStdName("fchmod")
64+
) and
65+
msg = "Using umask(0) may not be safe with call $@."
66+
or
67+
fc.getTarget().hasGlobalOrStdName("umask") and
68+
exists(FunctionCall fctmp |
69+
(
70+
fctmp.getTarget().hasGlobalOrStdName("chmod") or
71+
fctmp.getTarget().hasGlobalOrStdName("fchmod")
72+
) and
73+
(
74+
globalValueNumber(fc.getArgument(0)) = globalValueNumber(fctmp.getArgument(1)) and
75+
fc.getArgument(0).getValue() != "0"
76+
) and
77+
msg = "Not use equal argument in umask and $@ functions." and
78+
fcsnd = fctmp
79+
)
80+
or
81+
exists(ContainsArithmetic exptmp, int i |
82+
numberArgumentModFunctions(fc.getTarget(), i) and
83+
globalValueNumber(exptmp) = globalValueNumber(fc.getArgument(i)) and
84+
msg = "Using arithmetic to compute the mask in $@ may not be safe." and
85+
fcsnd = fc
86+
)
87+
select fc, msg, fcsnd, fcsnd.getTarget().getName()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| test.cpp:9:3:9:7 | call to umask | Not use equal argument in umask and $@ functions. | test.cpp:13:3:13:7 | call to chmod | chmod |
2+
| test.cpp:30:3:30:7 | call to chmod | Using arithmetic to compute the mask in $@ may not be safe. | test.cpp:30:3:30:7 | call to chmod | chmod |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/Security/CWE/CWE-266/IncorrectPrivilegeAssignment.ql
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
typedef int FILE;
2+
FILE *fopen(const char *filename, const char *mode);
3+
int umask(int pmode);
4+
int chmod(char * filename,int pmode);
5+
int fclose(FILE *stream);
6+
7+
void funcTest1()
8+
{
9+
umask(0666); // BAD
10+
FILE *fe;
11+
fe = fopen("myFile.txt", "wt");
12+
fclose(fe);
13+
chmod("myFile.txt",0666);
14+
}
15+
void funcTest1g()
16+
{
17+
umask(0022);
18+
FILE *fe;
19+
fe = fopen("myFile.txt", "wt");
20+
fclose(fe);
21+
chmod("myFile.txt",0666); // GOOD
22+
}
23+
24+
void funcTest2(int mode)
25+
{
26+
umask(mode);
27+
FILE *fe;
28+
fe = fopen("myFile.txt", "wt");
29+
fclose(fe);
30+
chmod("myFile.txt",0555-mode); // BAD
31+
}
32+
33+
void funcTest2g(int mode)
34+
{
35+
umask(mode);
36+
FILE *fe;
37+
fe = fopen("myFile.txt", "wt");
38+
fclose(fe);
39+
chmod("myFile.txt",0555&~mode); // GOOD
40+
}
41+
42+
int main(int argc, char *argv[])
43+
{
44+
funcTest1();
45+
funcTest2(27);
46+
funcTest1g();
47+
funcTest2g(27);
48+
return 0;
49+
}

0 commit comments

Comments
 (0)