11/**
2- * Provides implementation classes modeling `sscanf`, `fscanf` and various similar
3- * functions. See `semmle.code.cpp.models.Models` for usage information.
2+ * Provides implementation classes modeling the `scanf` family of functions.
3+ * See `semmle.code.cpp.models.Models` for usage information.
44 */
55
66import semmle.code.cpp.Function
@@ -9,18 +9,15 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
99import semmle.code.cpp.models.interfaces.Taint
1010import semmle.code.cpp.models.interfaces.Alias
1111import semmle.code.cpp.models.interfaces.SideEffect
12+ import semmle.code.cpp.models.interfaces.FlowSource
1213
1314/**
14- * The standard function `sscanf`, `fscanf` and its assorted variants
15+ * The `scanf` family of functions.
1516 */
16- private class SscanfModel extends ArrayFunction , TaintFunction , AliasFunction , SideEffectFunction {
17- SscanfModel ( ) { this instanceof Sscanf or this instanceof Fscanf or this instanceof Snscanf }
18-
17+ abstract private class ScanfFunctionModel extends ArrayFunction , TaintFunction , AliasFunction ,
18+ SideEffectFunction {
1919 override predicate hasArrayWithNullTerminator ( int bufParam ) {
2020 bufParam = this .( ScanfFunction ) .getFormatParameterIndex ( )
21- or
22- not this instanceof Fscanf and
23- bufParam = this .( ScanfFunction ) .getInputParameterIndex ( )
2421 }
2522
2623 override predicate hasArrayInput ( int bufParam ) { this .hasArrayWithNullTerminator ( bufParam ) }
@@ -36,7 +33,7 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
3633 )
3734 }
3835
39- private int getArgsStartPosition ( ) { result = this .getNumberOfParameters ( ) }
36+ int getArgsStartPosition ( ) { result = this .getNumberOfParameters ( ) }
4037
4138 override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
4239 input .isParameterDeref ( this .( ScanfFunction ) .getInputParameterIndex ( ) ) and
@@ -70,3 +67,36 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
7067 ]
7168 }
7269}
70+
71+ /**
72+ * The standard function `scanf` and its assorted variants
73+ */
74+ private class ScanfModel extends ScanfFunctionModel , LocalFlowSourceFunction instanceof Scanf {
75+ override predicate hasLocalFlowSource ( FunctionOutput output , string description ) {
76+ output .isParameterDeref ( any ( int i | i >= this .getArgsStartPosition ( ) ) ) and
77+ description = "Value read by " + this .getName ( )
78+ }
79+ }
80+
81+ /**
82+ * The standard function `fscanf` and its assorted variants
83+ */
84+ private class FscanfModel extends ScanfFunctionModel , RemoteFlowSourceFunction instanceof Fscanf {
85+ override predicate hasRemoteFlowSource ( FunctionOutput output , string description ) {
86+ output .isParameterDeref ( any ( int i | i >= this .getArgsStartPosition ( ) ) ) and
87+ description = "Value read by " + this .getName ( )
88+ }
89+ }
90+
91+ /**
92+ * The standard function `sscanf` and its assorted variants
93+ */
94+ private class SscanfModel extends ScanfFunctionModel {
95+ SscanfModel ( ) { this instanceof Sscanf or this instanceof Snscanf }
96+
97+ override predicate hasArrayWithNullTerminator ( int bufParam ) {
98+ super .hasArrayWithNullTerminator ( bufParam )
99+ or
100+ bufParam = this .( ScanfFunction ) .getInputParameterIndex ( )
101+ }
102+ }
0 commit comments