Merge pull request #4750 from geoffw0/modelclasses

C++: Model classes in StdString.qll.
This commit is contained in:
Jonas Jensen
2021-01-19 12:51:30 +01:00
committed by GitHub
4 changed files with 64 additions and 36 deletions

View File

@@ -334,6 +334,18 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
)
}
/**
* Gets the class of which this function, called `memberName`, is a member.
*
* Prefer to use `getDeclaringType()` or `getName()` directly if you do not
* need to reason about both.
*/
pragma[nomagic]
Class getClassAndName(string memberName) {
this.hasName(memberName) and
this.getDeclaringType() = result
}
/**
* Implements `ControlFlowNode.getControlFlowScope`. The `Function` is
* used to represent the exit node of the control flow graph, so it is

View File

@@ -9,9 +9,9 @@ import semmle.code.cpp.models.interfaces.Iterator
import semmle.code.cpp.models.interfaces.DataFlow
/**
* The `std::basic_string` template class.
* The `std::basic_string` template class instantiations.
*/
private class StdBasicString extends TemplateClass {
private class StdBasicString extends ClassTemplateInstantiation {
StdBasicString() { this.hasQualifiedName("std", "basic_string") }
}
@@ -24,7 +24,7 @@ private class StdBasicString extends TemplateClass {
* ```
*/
private class StdStringConstructor extends Constructor, TaintFunction {
StdStringConstructor() { this.getDeclaringType().hasQualifiedName("std", "basic_string") }
StdStringConstructor() { this.getDeclaringType() instanceof StdBasicString }
/**
* Gets the index of a parameter to this function that is a string (or
@@ -69,7 +69,7 @@ private class StdStringConstructor extends Constructor, TaintFunction {
* The `std::string` function `c_str`.
*/
private class StdStringCStr extends TaintFunction {
StdStringCStr() { this.hasQualifiedName("std", "basic_string", "c_str") }
StdStringCStr() { this.getClassAndName("c_str") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string itself (qualifier) to return value
@@ -82,7 +82,7 @@ private class StdStringCStr extends TaintFunction {
* The `std::string` function `data`.
*/
private class StdStringData extends TaintFunction {
StdStringData() { this.hasQualifiedName("std", "basic_string", "data") }
StdStringData() { this.getClassAndName("data") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string itself (qualifier) to return value
@@ -100,7 +100,7 @@ private class StdStringData extends TaintFunction {
* The `std::string` function `push_back`.
*/
private class StdStringPush extends TaintFunction {
StdStringPush() { this.hasQualifiedName("std", "basic_string", "push_back") }
StdStringPush() { this.getClassAndName("push_back") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to qualifier
@@ -113,7 +113,7 @@ private class StdStringPush extends TaintFunction {
* The `std::string` functions `front` and `back`.
*/
private class StdStringFrontBack extends TaintFunction {
StdStringFrontBack() { this.hasQualifiedName("std", "basic_string", ["front", "back"]) }
StdStringFrontBack() { this.getClassAndName(["front", "back"]) instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from object to returned reference
@@ -123,12 +123,12 @@ private class StdStringFrontBack extends TaintFunction {
}
/**
* The `std::string` function `operator+`.
* The (non-member) `std::string` function `operator+`.
*/
private class StdStringPlus extends TaintFunction {
StdStringPlus() {
this.hasQualifiedName("std", "operator+") and
this.getUnspecifiedType() = any(StdBasicString s).getAnInstantiation()
this.getUnspecifiedType() instanceof StdBasicString
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -148,7 +148,7 @@ private class StdStringPlus extends TaintFunction {
*/
private class StdStringAppend extends TaintFunction {
StdStringAppend() {
this.hasQualifiedName("std", "basic_string", ["operator+=", "append", "insert", "replace"])
this.getClassAndName(["operator+=", "append", "insert", "replace"]) instanceof StdBasicString
}
/**
@@ -190,7 +190,7 @@ private class StdStringAppend extends TaintFunction {
* The standard function `std::string.assign`.
*/
private class StdStringAssign extends TaintFunction {
StdStringAssign() { this.hasQualifiedName("std", "basic_string", "assign") }
StdStringAssign() { this.getClassAndName("assign") instanceof StdBasicString }
/**
* Gets the index of a parameter to this function that is a string (or
@@ -230,7 +230,7 @@ private class StdStringAssign extends TaintFunction {
* The standard function `std::string.copy`.
*/
private class StdStringCopy extends TaintFunction {
StdStringCopy() { this.hasQualifiedName("std", "basic_string", "copy") }
StdStringCopy() { this.getClassAndName("copy") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// copy(dest, num, pos)
@@ -243,7 +243,7 @@ private class StdStringCopy extends TaintFunction {
* The standard function `std::string.substr`.
*/
private class StdStringSubstr extends TaintFunction {
StdStringSubstr() { this.hasQualifiedName("std", "basic_string", "substr") }
StdStringSubstr() { this.getClassAndName("substr") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// substr(pos, num)
@@ -252,11 +252,18 @@ private class StdStringSubstr extends TaintFunction {
}
}
/**
* The `std::basic_stringstream` template class instantiations.
*/
private class StdBasicStringStream extends ClassTemplateInstantiation {
StdBasicStringStream() { this.hasQualifiedName("std", "basic_stringstream") }
}
/**
* The `std::string` functions `at` and `operator[]`.
*/
private class StdStringAt extends TaintFunction {
StdStringAt() { this.hasQualifiedName("std", "basic_string", ["at", "operator[]"]) }
StdStringAt() { this.getClassAndName(["at", "operator[]"]) instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to referenced return value
@@ -270,9 +277,9 @@ private class StdStringAt extends TaintFunction {
}
/**
* The `std::basic_istream` template class.
* The `std::basic_istream` template class instantiations.
*/
private class StdBasicIStream extends TemplateClass {
private class StdBasicIStream extends ClassTemplateInstantiation {
StdBasicIStream() { this.hasQualifiedName("std", "basic_istream") }
}
@@ -280,7 +287,7 @@ private class StdBasicIStream extends TemplateClass {
* The `std::istream` function `operator>>` (defined as a member function).
*/
private class StdIStreamIn extends DataFlowFunction, TaintFunction {
StdIStreamIn() { this.hasQualifiedName("std", "basic_istream", "operator>>") }
StdIStreamIn() { this.getClassAndName("operator>>") instanceof StdBasicIStream }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// returns reference to `*this`
@@ -305,8 +312,7 @@ private class StdIStreamIn extends DataFlowFunction, TaintFunction {
private class StdIStreamInNonMember extends DataFlowFunction, TaintFunction {
StdIStreamInNonMember() {
this.hasQualifiedName("std", "operator>>") and
this.getUnspecifiedType().(ReferenceType).getBaseType() =
any(StdBasicIStream s).getAnInstantiation()
this.getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdBasicIStream
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
@@ -331,7 +337,7 @@ private class StdIStreamInNonMember extends DataFlowFunction, TaintFunction {
*/
private class StdIStreamGet extends TaintFunction {
StdIStreamGet() {
this.hasQualifiedName("std", "basic_istream", ["get", "peek"]) and
this.getClassAndName(["get", "peek"]) instanceof StdBasicIStream and
this.getNumberOfParameters() = 0
}
@@ -347,7 +353,7 @@ private class StdIStreamGet extends TaintFunction {
*/
private class StdIStreamRead extends DataFlowFunction, TaintFunction {
StdIStreamRead() {
this.hasQualifiedName("std", "basic_istream", ["get", "read"]) and
this.getClassAndName(["get", "read"]) instanceof StdBasicIStream and
this.getNumberOfParameters() > 0
}
@@ -372,7 +378,7 @@ private class StdIStreamRead extends DataFlowFunction, TaintFunction {
* The `std::istream` function `readsome`.
*/
private class StdIStreamReadSome extends TaintFunction {
StdIStreamReadSome() { this.hasQualifiedName("std", "basic_istream", "readsome") }
StdIStreamReadSome() { this.getClassAndName("readsome") instanceof StdBasicIStream }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to first parameter
@@ -385,7 +391,7 @@ private class StdIStreamReadSome extends TaintFunction {
* The `std::istream` function `putback`.
*/
private class StdIStreamPutBack extends DataFlowFunction, TaintFunction {
StdIStreamPutBack() { this.hasQualifiedName("std", "basic_istream", "putback") }
StdIStreamPutBack() { this.getClassAndName("putback") instanceof StdBasicIStream }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// returns reference to `*this`
@@ -418,7 +424,7 @@ private class StdIStreamPutBack extends DataFlowFunction, TaintFunction {
* The `std::istream` function `getline`.
*/
private class StdIStreamGetLine extends DataFlowFunction, TaintFunction {
StdIStreamGetLine() { this.hasQualifiedName("std", "basic_istream", "getline") }
StdIStreamGetLine() { this.getClassAndName("getline") instanceof StdBasicIStream }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// returns reference to `*this`
@@ -461,9 +467,9 @@ private class StdGetLine extends DataFlowFunction, TaintFunction {
}
/**
* The `std::basic_ostream` template class.
* The `std::basic_ostream` template class instantiations.
*/
private class StdBasicOStream extends TemplateClass {
private class StdBasicOStream extends ClassTemplateInstantiation {
StdBasicOStream() { this.hasQualifiedName("std", "basic_ostream") }
}
@@ -472,7 +478,9 @@ private class StdBasicOStream extends TemplateClass {
* `put` and `write`.
*/
private class StdOStreamOut extends DataFlowFunction, TaintFunction {
StdOStreamOut() { this.hasQualifiedName("std", "basic_ostream", ["operator<<", "put", "write"]) }
StdOStreamOut() {
this.getClassAndName(["operator<<", "put", "write"]) instanceof StdBasicOStream
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// returns reference to `*this`
@@ -507,8 +515,7 @@ private class StdOStreamOut extends DataFlowFunction, TaintFunction {
private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction {
StdOStreamOutNonMember() {
this.hasQualifiedName("std", "operator<<") and
this.getUnspecifiedType().(ReferenceType).getBaseType() =
any(StdBasicOStream s).getAnInstantiation()
this.getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdBasicOStream
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
@@ -537,9 +544,7 @@ private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction {
* input parameter.
*/
private class StdStringStreamConstructor extends Constructor, TaintFunction {
StdStringStreamConstructor() {
this.getDeclaringType().hasQualifiedName("std", "basic_stringstream")
}
StdStringStreamConstructor() { this.getDeclaringType() instanceof StdBasicStringStream }
/**
* Gets the index of a parameter to this function that is a string.
@@ -563,7 +568,7 @@ private class StdStringStreamConstructor extends Constructor, TaintFunction {
* The `std::stringstream` function `str`.
*/
private class StdStringStreamStr extends TaintFunction {
StdStringStreamStr() { this.hasQualifiedName("std", "basic_stringstream", "str") }
StdStringStreamStr() { this.getClassAndName("str") instanceof StdBasicStringStream }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to return value (if any)
@@ -576,15 +581,24 @@ private class StdStringStreamStr extends TaintFunction {
}
}
/**
* The `std::basic_ios` template class instantiations.
*/
private class StdBasicIOS extends ClassTemplateInstantiation {
StdBasicIOS() { this.hasQualifiedName("std", "basic_ios") }
}
/**
* A `std::` stream function that does not require a model, except that it
* returns a reference to `*this` and thus could be used in a chain.
*/
private class StdStreamFunction extends DataFlowFunction, TaintFunction {
StdStreamFunction() {
this.hasQualifiedName("std", "basic_istream", ["ignore", "unget", "seekg"]) or
this.hasQualifiedName("std", "basic_ostream", ["seekp", "flush"]) or
this.hasQualifiedName("std", "basic_ios", "copyfmt")
this.getClassAndName(["ignore", "unget", "seekg"]) instanceof StdBasicIStream
or
this.getClassAndName(["seekp", "flush"]) instanceof StdBasicOStream
or
this.getClassAndName("copyfmt") instanceof StdBasicIOS
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {

View File

@@ -24,5 +24,6 @@ abstract class DataFlowFunction extends Function {
* represented by `input` to the return value or buffer represented by
* `output`
*/
pragma[nomagic]
abstract predicate hasDataFlow(FunctionInput input, FunctionOutput output);
}

View File

@@ -28,5 +28,6 @@ abstract class TaintFunction extends Function {
* Holds if data passed into the argument, qualifier, or buffer represented by
* `input` influences the return value or buffer represented by `output`
*/
pragma[nomagic]
abstract predicate hasTaintFlow(FunctionInput input, FunctionOutput output);
}