C++: Create a module for models of things in Std.

This commit is contained in:
Geoffrey White
2020-10-19 18:27:20 +01:00
parent 3fad597bbf
commit ddc5150080

View File

@@ -4,45 +4,47 @@
import semmle.code.cpp.models.interfaces.Taint
/**
* Additional model for `std::pair` constructors.
*/
private class StdPairConstructor extends Constructor, TaintFunction {
StdPairConstructor() { this.hasQualifiedName("std", "pair", "pair") }
module Std {
/**
* Additional model for `std::pair` constructors.
*/
private class PairConstructor extends Constructor, TaintFunction {
PairConstructor() { this.hasQualifiedName("std", "pair", "pair") }
/**
* Gets the index of a parameter to this function that is a reference to
* either value type of the pair.
*/
int getAValueTypeParameterIndex() {
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(_).(Type).getUnspecifiedType() // i.e. the `T1` or `T2` of this `std::pair<T1, T2>`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from second parameter of a value type to the qualifier
getAValueTypeParameterIndex() = 1 and
input.isParameterDeref(1) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
output.isQualifierObject()
)
}
}
/**
* Gets the index of a parameter to this function that is a reference to
* either value type of the pair.
* The standard pair `swap` function.
*/
int getAValueTypeParameterIndex() {
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(_).(Type).getUnspecifiedType() // i.e. the `T1` or `T2` of this `std::pair<T1, T2>`
}
private class PairSwap extends TaintFunction {
PairSwap() { this.hasQualifiedName("std", "pair", "swap") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from second parameter of a value type to the qualifier
getAValueTypeParameterIndex() = 1 and
input.isParameterDeref(1) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// container1.swap(container2)
input.isQualifierObject() and
output.isParameterDeref(0)
or
input.isParameterDeref(0) and
output.isQualifierObject()
)
}
}
/**
* The standard pair `swap` function.
*/
private class StdPairSwap extends TaintFunction {
StdPairSwap() { this.hasQualifiedName("std", "pair", "swap") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// container1.swap(container2)
input.isQualifierObject() and
output.isParameterDeref(0)
or
input.isParameterDeref(0) and
output.isQualifierObject()
}
}
}