C++: add local flow sources

This commit is contained in:
Robert Marsh
2020-05-19 11:07:12 -07:00
committed by Mathias Vorreiter Pedersen
parent 19fac60e6d
commit 74e05c111e
4 changed files with 95 additions and 6 deletions

View File

@@ -1,6 +1,7 @@
private import implementations.Allocation
private import implementations.Deallocation
private import implementations.Fread
private import implementations.Getenv
private import implementations.Gets
private import implementations.IdentityFunction
private import implementations.Inet

View File

@@ -0,0 +1,22 @@
/**
* Provides an implementation class modelling the POSIX function `getenv`.
*/
import cpp
import semmle.code.cpp.models.interfaces.FlowSource
/**
* The POSIX function `getenv`.
*/
class Getenv extends LocalFlowFunction {
Getenv() {
this.hasGlobalName("getenv")
}
override predicate hasLocalFlowSource (FunctionOutput output, string description) {
(
output.isReturnValueDeref() or
output.isReturnValue()
) and
description = "an environment variable"
}
}

View File

@@ -11,7 +11,7 @@ import FunctionInputsAndOutputs
import semmle.code.cpp.models.Models
/**
* A library function which returns data read from a network connection.
* A library function which returns data that may be read from a network connection.
*/
abstract class RemoteFlowFunction extends Function {
/**
@@ -19,3 +19,13 @@ abstract class RemoteFlowFunction extends Function {
*/
abstract predicate hasRemoteFlowSource(FunctionOutput output, string description);
}
/**
* A library function which returns data that is directly controlled by a user.
*/
abstract class LocalFlowFunction extends Function {
/**
* Holds if data described by `description` flows from `output` of a call to this function.
*/
abstract predicate hasLocalFlowSource(FunctionOutput output, string description);
}

View File

@@ -13,25 +13,35 @@ abstract class RemoteFlowSource extends DataFlow::Node {
abstract string getSourceType();
}
private class TaintedReturnSource extends RemoteFlowSource {
/** A data flow source of local user input. */
abstract class LocalFlowSource extends DataFlow::Node {
/** Gets a string that describes the type of this local flow source. */
abstract string getSourceType();
}
private class RemoteReturnSource extends RemoteFlowSource {
string sourceType;
TaintedReturnSource() {
RemoteReturnSource() {
exists(RemoteFlowFunction func, CallInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getStaticCallTarget() = func and
func.hasRemoteFlowSource(output, sourceType) and
output.isReturnValue()
(
output.isReturnValue()
or
output.isReturnValueDeref()
)
)
}
override string getSourceType() { result = sourceType }
}
private class TaintedParameterSource extends RemoteFlowSource {
private class RemoteParameterSource extends RemoteFlowSource {
string sourceType;
TaintedParameterSource() {
RemoteParameterSource() {
exists(RemoteFlowFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
@@ -42,3 +52,49 @@ private class TaintedParameterSource extends RemoteFlowSource {
override string getSourceType() { result = sourceType }
}
private class LocalReturnSource extends LocalFlowSource {
string sourceType;
LocalReturnSource() {
exists(LocalFlowFunction func, CallInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getStaticCallTarget() = func and
func.hasLocalFlowSource(output, sourceType) and
(
output.isReturnValue()
or
output.isReturnValueDeref()
)
)
}
override string getSourceType() { result = sourceType }
}
private class LocalParameterSource extends LocalFlowSource {
string sourceType;
LocalParameterSource() {
exists(LocalFlowFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
func.hasLocalFlowSource(output, sourceType) and
output.isParameterDeref(instr.getIndex())
)
}
override string getSourceType() { result = sourceType }
}
private class ArgvSource extends LocalFlowSource {
ArgvSource() {
exists(Parameter argv |
argv.hasName("argv") and
argv.getFunction().hasGlobalName("main") and
this.asExpr() = argv.getAnAccess()
)
}
override string getSourceType() { result = "a command line argument" }
}