Skip to content

Commit dba5c85

Browse files
committed
C++: Avoid using the function to model the flow source'ness of scanf and fscanf.
1 parent 9dbf5bb commit dba5c85

1 file changed

Lines changed: 21 additions & 10 deletions

File tree

  • cpp/ql/lib/semmle/code/cpp/models/implementations

cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import semmle.code.cpp.models.interfaces.Taint
1010
import semmle.code.cpp.models.interfaces.Alias
1111
import semmle.code.cpp.models.interfaces.SideEffect
1212
import semmle.code.cpp.models.interfaces.FlowSource
13+
private import semmle.code.cpp.security.FlowSources
1314

1415
/**
1516
* The `scanf` family of functions.
@@ -72,21 +73,31 @@ abstract private class ScanfFunctionModel extends ArrayFunction, TaintFunction,
7273
/**
7374
* The standard function `scanf` and its assorted variants
7475
*/
75-
private class ScanfModel extends ScanfFunctionModel, LocalFlowSourceFunction instanceof Scanf {
76-
override predicate hasLocalFlowSource(FunctionOutput output, string description) {
77-
output.isParameterDeref(any(int i | i >= this.getArgsStartPosition())) and
78-
description = "value read by " + this.getName()
79-
}
76+
private class ScanfModel extends ScanfFunctionModel instanceof Scanf { }
77+
78+
abstract private class AbstractScanfFlowSource extends DataFlow::Node {
79+
ScanfFunctionCall scanf;
80+
81+
AbstractScanfFlowSource() { this.asDefiningArgument(1) = scanf.getAnOutputArgument() }
82+
83+
string getSourceType() { result = "value read by " + scanf.getScanfFunction().getName() }
84+
}
85+
86+
private class ScanfFlowSource extends AbstractScanfFlowSource, LocalFlowSource {
87+
ScanfFlowSource() { not scanf.getScanfFunction() instanceof Fscanf }
88+
89+
final override string getSourceType() { result = AbstractScanfFlowSource.super.getSourceType() }
8090
}
8191

8292
/**
8393
* The standard function `fscanf` and its assorted variants
8494
*/
85-
private class FscanfModel extends ScanfFunctionModel, RemoteFlowSourceFunction instanceof Fscanf {
86-
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
87-
output.isParameterDeref(any(int i | i >= this.getArgsStartPosition())) and
88-
description = "value read by " + this.getName()
89-
}
95+
private class FscanfModel extends ScanfFunctionModel instanceof Fscanf { }
96+
97+
private class FScanfFlowSource extends AbstractScanfFlowSource, RemoteFlowSource {
98+
FScanfFlowSource() { scanf.getScanfFunction() instanceof Fscanf }
99+
100+
final override string getSourceType() { result = AbstractScanfFlowSource.super.getSourceType() }
90101
}
91102

92103
/**

0 commit comments

Comments
 (0)