mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Merge pull request #3273 from Semmle/rdmarsh/cpp/RemoteFlowSource-model
C++: Add remote flow sources via models
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import semmle.code.cpp.models.interfaces.Alias
|
||||
import semmle.code.cpp.models.interfaces.FlowSource
|
||||
|
||||
class Fread extends AliasFunction {
|
||||
class Fread extends AliasFunction, RemoteFlowFunction {
|
||||
Fread() { this.hasGlobalName("fread") }
|
||||
|
||||
override predicate parameterNeverEscapes(int n) {
|
||||
@@ -11,4 +12,9 @@ class Fread extends AliasFunction {
|
||||
override predicate parameterEscapesOnlyViaReturn(int n) { none() }
|
||||
|
||||
override predicate parameterIsAlwaysReturned(int n) { none() }
|
||||
|
||||
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
|
||||
output.isParameterDeref(0) and
|
||||
description = "String read by " + this.getName()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@ import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.ArrayFunction
|
||||
import semmle.code.cpp.models.interfaces.Alias
|
||||
import semmle.code.cpp.models.interfaces.SideEffect
|
||||
import semmle.code.cpp.models.interfaces.FlowSource
|
||||
|
||||
/**
|
||||
* The standard functions `gets` and `fgets`.
|
||||
*/
|
||||
class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction,
|
||||
SideEffectFunction {
|
||||
SideEffectFunction, RemoteFlowFunction {
|
||||
GetsFunction() {
|
||||
exists(string name | hasGlobalOrStdName(name) |
|
||||
name = "gets" or // gets(str)
|
||||
@@ -42,4 +43,9 @@ class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, Alias
|
||||
buffer = true and
|
||||
mustWrite = true
|
||||
}
|
||||
|
||||
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
|
||||
output.isParameterDeref(0) and
|
||||
description = "String read by " + this.getName()
|
||||
}
|
||||
}
|
||||
|
||||
21
cpp/ql/src/semmle/code/cpp/models/interfaces/FlowSource.qll
Normal file
21
cpp/ql/src/semmle/code/cpp/models/interfaces/FlowSource.qll
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Provides a class for modeling functions that return data from potentially untrusted sources. To use
|
||||
* this QL library, create a QL class extending `DataFlowFunction` with a
|
||||
* characteristic predicate that selects the function or set of functions you
|
||||
* are modeling. Within that class, override the predicates provided by
|
||||
* `RemoteFlowFunction` to match the flow within that function.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import FunctionInputsAndOutputs
|
||||
import semmle.code.cpp.models.Models
|
||||
|
||||
/**
|
||||
* A library function which returns data read from a network connection.
|
||||
*/
|
||||
abstract class RemoteFlowFunction extends Function {
|
||||
/**
|
||||
* Holds if remote data described by `description` flows from `output` of a call to this function.
|
||||
*/
|
||||
abstract predicate hasRemoteFlowSource(FunctionOutput output, string description);
|
||||
}
|
||||
44
cpp/ql/src/semmle/code/cpp/security/FlowSources.qll
Normal file
44
cpp/ql/src/semmle/code/cpp/security/FlowSources.qll
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Provides classes representing various flow sources for taint tracking.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.models.interfaces.FlowSource
|
||||
|
||||
/** A data flow source of remote user input. */
|
||||
abstract class RemoteFlowSource extends DataFlow::Node {
|
||||
/** Gets a string that describes the type of this remote flow source. */
|
||||
abstract string getSourceType();
|
||||
}
|
||||
|
||||
private class TaintedReturnSource extends RemoteFlowSource {
|
||||
string sourceType;
|
||||
|
||||
TaintedReturnSource() {
|
||||
exists(RemoteFlowFunction func, CallInstruction instr, FunctionOutput output |
|
||||
asInstruction() = instr and
|
||||
instr.getStaticCallTarget() = func and
|
||||
func.hasRemoteFlowSource(output, sourceType) and
|
||||
output.isReturnValue()
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = sourceType }
|
||||
}
|
||||
|
||||
private class TaintedParameterSource extends RemoteFlowSource {
|
||||
string sourceType;
|
||||
|
||||
TaintedParameterSource() {
|
||||
exists(RemoteFlowFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
|
||||
asInstruction() = instr and
|
||||
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
|
||||
func.hasRemoteFlowSource(output, sourceType) and
|
||||
output.isParameterDeref(instr.getIndex())
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = sourceType }
|
||||
}
|
||||
Reference in New Issue
Block a user