1313
1414import cpp
1515import semmle.code.cpp.ir.dataflow.DataFlow
16- import semmle.code.cpp.ir.dataflow.DataFlow2
1716
1817predicate isCreateProcessFunction ( FunctionCall call , int applicationNameIndex , int commandLineIndex ) {
1918 call .getTarget ( ) .hasGlobalName ( "CreateProcessA" ) and
@@ -55,42 +54,40 @@ class CreateProcessFunctionCall extends FunctionCall {
5554/**
5655 * Dataflow that detects a call to CreateProcess with a NULL value for lpApplicationName argument
5756 */
58- class NullAppNameCreateProcessFunctionConfiguration extends DataFlow:: Configuration {
59- NullAppNameCreateProcessFunctionConfiguration ( ) {
60- this = "NullAppNameCreateProcessFunctionConfiguration"
61- }
62-
63- override predicate isSource ( DataFlow:: Node source ) { source .asExpr ( ) instanceof NullValue }
57+ module NullAppNameCreateProcessFunctionConfiguration implements DataFlow:: ConfigSig {
58+ predicate isSource ( DataFlow:: Node source ) { source .asExpr ( ) instanceof NullValue }
6459
65- override predicate isSink ( DataFlow:: Node sink ) {
60+ predicate isSink ( DataFlow:: Node sink ) {
6661 exists ( CreateProcessFunctionCall call , Expr val | val = sink .asExpr ( ) |
6762 val = call .getArgument ( call .getApplicationNameArgumentId ( ) )
6863 )
6964 }
7065}
7166
67+ module NullAppNameCreateProcessFunction =
68+ DataFlow:: Make< NullAppNameCreateProcessFunctionConfiguration > ;
69+
7270/**
7371 * Dataflow that detects a call to CreateProcess with an unquoted commandLine argument
7472 */
75- class QuotedCommandInCreateProcessFunctionConfiguration extends DataFlow2:: Configuration {
76- QuotedCommandInCreateProcessFunctionConfiguration ( ) {
77- this = "QuotedCommandInCreateProcessFunctionConfiguration"
78- }
79-
80- override predicate isSource ( DataFlow2:: Node source ) {
73+ module QuotedCommandInCreateProcessFunctionConfiguration implements DataFlow:: ConfigSig {
74+ predicate isSource ( DataFlow:: Node source ) {
8175 exists ( string s |
8276 s = source .asExpr ( ) .getValue ( ) .toString ( ) and
8377 not isQuotedOrNoSpaceApplicationNameOnCmd ( s )
8478 )
8579 }
8680
87- override predicate isSink ( DataFlow2 :: Node sink ) {
81+ predicate isSink ( DataFlow :: Node sink ) {
8882 exists ( CreateProcessFunctionCall call , Expr val | val = sink .asExpr ( ) |
8983 val = call .getArgument ( call .getCommandLineArgumentId ( ) )
9084 )
9185 }
9286}
9387
88+ module QuotedCommandInCreateProcessFunction =
89+ DataFlow:: Make< QuotedCommandInCreateProcessFunctionConfiguration > ;
90+
9491bindingset [ s]
9592predicate isQuotedOrNoSpaceApplicationNameOnCmd ( string s ) {
9693 s .regexpMatch ( "\"([^\"])*\"[\\s\\S]*" ) // The first element (path) is quoted
@@ -100,14 +97,14 @@ predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s) {
10097
10198from CreateProcessFunctionCall call , string msg1 , string msg2
10299where
103- exists ( Expr appName , NullAppNameCreateProcessFunctionConfiguration nullAppConfig |
100+ exists ( Expr appName |
104101 appName = call .getArgument ( call .getApplicationNameArgumentId ( ) ) and
105- nullAppConfig . hasFlowToExpr ( appName ) and
102+ NullAppNameCreateProcessFunction :: hasFlowToExpr ( appName ) and
106103 msg1 = call .toString ( ) + " with lpApplicationName == NULL (" + appName + ")"
107104 ) and
108- exists ( Expr cmd , QuotedCommandInCreateProcessFunctionConfiguration quotedConfig |
105+ exists ( Expr cmd |
109106 cmd = call .getArgument ( call .getCommandLineArgumentId ( ) ) and
110- quotedConfig . hasFlowToExpr ( cmd ) and
107+ QuotedCommandInCreateProcessFunction :: hasFlowToExpr ( cmd ) and
111108 msg2 =
112109 " and with an unquoted lpCommandLine (" + cmd +
113110 ") introduces a security vulnerability if the path contains spaces."
0 commit comments