Skip to content

Commit e3ea775

Browse files
committed
C++: Define sources better so that we catch all the test cases.
1 parent ae1f5bb commit e3ea775

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

cpp/ql/src/experimental/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser.ql

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,33 @@
1717
import cpp
1818
import semmle.code.cpp.dataflow.DataFlow
1919

20+
/**
21+
* A Linux system call.
22+
*/
23+
class SystemCallFunction extends Function {
24+
SystemCallFunction() {
25+
this.getName().matches("SYSC\\_%")
26+
}
27+
}
28+
29+
/**
30+
* A value that comes from a Linux system call (sources).
31+
*/
32+
class SystemParameterSource extends DataFlow::Node {
33+
SystemParameterSource() {
34+
exists(FunctionCall fc |
35+
fc.getTarget() instanceof SystemCallFunction and
36+
(
37+
this.asDefiningArgument() = fc.getAnArgument().getAChild*() or
38+
this.asExpr() = fc
39+
)
40+
)
41+
}
42+
}
43+
44+
/**
45+
* Macros used to check the value (barriers).
46+
*/
2047
class WriteAccessCheckMacro extends Macro {
2148
VariableAccess va;
2249

@@ -28,6 +55,9 @@ class WriteAccessCheckMacro extends Macro {
2855
VariableAccess getArgument() { result = va }
2956
}
3057

58+
/**
59+
* The `unsafe_put_user` macro and its uses (sinks).
60+
*/
3161
class UnSafePutUserMacro extends Macro {
3262
PointerDereferenceExpr writeUserPtr;
3363

@@ -42,15 +72,13 @@ class UnSafePutUserMacro extends Macro {
4272
}
4373
}
4474

45-
class ExploitableUserModePtrParam extends Parameter {
75+
class ExploitableUserModePtrParam extends SystemParameterSource {
4676
ExploitableUserModePtrParam() {
47-
not exists(WriteAccessCheckMacro writeAccessCheck |
48-
DataFlow::localFlow(DataFlow::parameterNode(this),
49-
DataFlow::exprNode(writeAccessCheck.getArgument()))
50-
) and
5177
exists(UnSafePutUserMacro unsafePutUser |
52-
DataFlow::localFlow(DataFlow::parameterNode(this),
53-
DataFlow::exprNode(unsafePutUser.getUserModePtr()))
78+
DataFlow::localFlow(this, DataFlow::exprNode(unsafePutUser.getUserModePtr()))
79+
) and
80+
not exists(WriteAccessCheckMacro writeAccessCheck |
81+
DataFlow::localFlow(this, DataFlow::exprNode(writeAccessCheck.getArgument()))
5482
)
5583
}
5684
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
| test.cpp:14:16:14:16 | p | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:14:16:14:16 | p | p |
1+
| test.cpp:16:22:16:23 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:16:22:16:23 | ref arg & ... | ref arg & ... |
2+
| test.cpp:37:22:37:23 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:37:22:37:23 | ref arg & ... | ref arg & ... |
3+
| test.cpp:65:22:65:28 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:65:22:65:28 | ref arg & ... | ref arg & ... |

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void test3()
3636

3737
SYSC_SOMESYSTEMCALL(&v);
3838

39-
unsafe_put_user(123, &v); // BAD [NOT DETECTED]
39+
unsafe_put_user(123, &v); // BAD
4040
}
4141

4242
void test4()
@@ -64,7 +64,7 @@ void test5()
6464

6565
SYSC_SOMESYSTEMCALL(&myData);
6666

67-
unsafe_put_user(123, &(myData.x)); // BAD [NOT DETECTED]
67+
unsafe_put_user(123, &(myData.x)); // BAD
6868
}
6969

7070
void test6()

0 commit comments

Comments
 (0)