C++: Add a MaD model for 'CRegKey' and mark query calls as local flow sources.

This commit is contained in:
Mathias Vorreiter Pedersen
2024-11-27 15:43:39 +00:00
parent 5aada39a4e
commit d69de0cc76
4 changed files with 116 additions and 9 deletions

View File

@@ -0,0 +1,19 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
- ["", "CRegKey", True, "CRegKey", "(CRegKey&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"]
- ["", "CRegKey", True, "CRegKey", "(HKEY)", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
- ["", "CRegKey", True, "Attach", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
- ["", "CRegKey", True, "QueryBinaryValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
- ["", "CRegKey", True, "QueryDWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
- ["", "CRegKey", True, "QueryMultiStringValue", "", "", "Argument[*0]", "Argument[**1]", "taint", "manual"]
- ["", "CRegKey", True, "QueryQWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
- ["", "CRegKey", True, "QueryStringValue", "", "", "Argument[*0]", "Argument[**1]", "taint", "manual"]
- ["", "CRegKey", True, "QueryValue", "(LPCTSTR,DWORD *,void *,ULONG *)", "", "Argument[*0]", "Argument[*2]", "taint", "manual"]
- ["", "CRegKey", True, "QueryValue", "(DWORD&,LPCTSTR)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
- ["", "CRegKey", True, "QueryValue", "(LPTSTR,LPCTSTR,DWORD *)", "", "Argument[*1]", "Argument[**0]", "taint", "manual"]
- ["", "CRegKey", True, "QueryValue", "operator HKEY", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
- ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"]
- ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "Argument[-1]", "value", "manual"]

View File

@@ -56,3 +56,4 @@ private import implementations.CPathT
private import implementations.CAtlFile
private import implementations.CAtlFileMapping
private import implementations.CAtlTemporaryFile
private import implementations.CRegKey

View File

@@ -0,0 +1,87 @@
private import cpp
private import semmle.code.cpp.models.interfaces.FlowSource
private import semmle.code.cpp.ir.dataflow.FlowSteps
private import semmle.code.cpp.dataflow.new.DataFlow
/** The `CRegKey` class from the Microsoft "Active Template Library". */
class CRegKey extends Class {
CRegKey() { this.hasGlobalName("CRegKey") }
}
module CRegKey {
/** The `m_hKey` member on a object of type `CRegKey`. */
class MhKey extends Field {
MhKey() {
this.getDeclaringType() instanceof CRegKey and
this.getName() = "m_hKey"
}
}
private class MhKeyPathTaintInheritingContent extends TaintInheritingContent,
DataFlow::FieldContent
{
MhKeyPathTaintInheritingContent() { this.getField() instanceof MhKey }
}
private class CRegKeyMemberFunction extends MemberFunction {
string name;
CRegKeyMemberFunction() { this.getClassAndName(name) instanceof CRegKey }
}
abstract private class CRegKeyFlowSource extends CRegKeyMemberFunction, LocalFlowSourceFunction {
FunctionOutput output;
final override predicate hasLocalFlowSource(FunctionOutput output_, string description) {
output_ = output and
description = "registry string read by " + name
}
}
/** The `CRegKey::QueryBinaryValue` function from Win32. */
class QueryBinaryValue extends CRegKeyFlowSource {
QueryBinaryValue() { name = "QueryBinaryValue" and output.isParameterDeref(1) }
}
/** The `CRegKey::QueryDWORDValue` function from Win32. */
class QueryDwordValue extends CRegKeyFlowSource {
QueryDwordValue() { name = "QueryDWORDValue" and output.isParameterDeref(1) }
}
/** The `CRegKey::QueryGUIDValue` function from Win32. */
class QueryGuidValue extends CRegKeyFlowSource {
QueryGuidValue() { name = "QueryGUIDValue" and output.isParameterDeref(1) }
}
/** The `CRegKey::QueryMultiStringValue` function from Win32. */
class QueryMultiStringValue extends CRegKeyFlowSource {
QueryMultiStringValue() { name = "QueryMultiStringValue" and output.isParameterDeref(1) }
}
/** The `CRegKey::QueryQWORDValue` function from Win32. */
class QueryQwordValue extends CRegKeyFlowSource {
QueryQwordValue() { name = "QueryQWORDValue" and output.isParameterDeref(1) }
}
/** The `CRegKey::QueryStringValue` function from Win32. */
class QueryStringValue extends CRegKeyFlowSource {
QueryStringValue() { name = "QueryStringValue" and output.isParameterDeref(1) }
}
/** The `CRegKey::QueryValue` function from Win32. */
class QueryValue extends CRegKeyFlowSource {
QueryValue() {
name = "QueryValue" and
(
this.getNumberOfParameters() = 4 and
output.isParameterDeref(2)
or
this.getNumberOfParameters() = 2 and
output.isParameterDeref(0)
or
this.getNumberOfParameters() = 3 and
output.isParameterDeref(0)
)
}
}
}

View File

@@ -364,26 +364,26 @@ void test_CRegKey() {
CRegKey key;
char data[1024];
ULONG bytesRead;
key.QueryBinaryValue("foo", data, &bytesRead); // $ MISSING: local_source
key.QueryBinaryValue("foo", data, &bytesRead); // $ local_source
DWORD value;
key.QueryDWORDValue("foo", value); // $ MISSING: local_source
key.QueryDWORDValue("foo", value); // $ local_source
GUID guid;
key.QueryGUIDValue("foo", guid); // $ MISSING: local_source
key.QueryGUIDValue("foo", guid); // $ local_source
key.QueryMultiStringValue("foo", data, &bytesRead); // $ MISSING: local_source
key.QueryMultiStringValue("foo", data, &bytesRead); // $ local_source
ULONGLONG qword;
key.QueryQWORDValue("foo", qword); // $ MISSING: local_source
key.QueryQWORDValue("foo", qword); // $ local_source
key.QueryStringValue("foo", data, &bytesRead); // $ MISSING: local_source
key.QueryStringValue("foo", data, &bytesRead); // $ local_source
key.QueryValue(data, "foo", &bytesRead); // $ MISSING: local_source
key.QueryValue(data, "foo", &bytesRead); // $ local_source
DWORD type;
key.QueryValue("foo", &type, data, &bytesRead); // $ MISSING: local_source
key.QueryValue("foo", &type, data, &bytesRead); // $ local_source
DWORD value2;
key.QueryValue(value2, "foo"); // $ MISSING: local_source
key.QueryValue(value2, "foo"); // $ local_source
}