1717import cpp
1818import 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+ */
2047class 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+ */
3161class 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}
0 commit comments