Merge branch 'main' into swap

This commit is contained in:
Geoffrey White
2020-12-14 17:54:11 +00:00
145 changed files with 13573 additions and 7982 deletions

View File

@@ -8,168 +8,41 @@ import semmle.code.cpp.AutogeneratedFile
predicate trivialPositiveIntValue(string s) {
// Small numbers
s = [0 .. 20].toString() or
// Popular powers of two (decimal)
s = "16" or
s = "24" or
s = "32" or
s = "64" or
s = "128" or
s = "256" or
s = "512" or
s = "1024" or
s = "2048" or
s = "4096" or
s = "16384" or
s = "32768" or
s = "65536" or
s = "1048576" or
s = "2147483648" or
s = "4294967296" or
// Popular powers of two, minus one (decimal)
s = "15" or
s = "31" or
s = "63" or
s = "127" or
s = "255" or
s = "511" or
s = "1023" or
s = "2047" or
s = "4095" or
s = "16383" or
s = "32767" or
s = "65535" or
s = "1048577" or
s = "2147483647" or
s = "4294967295" or
// Popular powers of two (32-bit hex)
s = "0x00000001" or
s = "0x00000002" or
s = "0x00000004" or
s = "0x00000008" or
s = "0x00000010" or
s = "0x00000020" or
s = "0x00000040" or
s = "0x00000080" or
s = "0x00000100" or
s = "0x00000200" or
s = "0x00000400" or
s = "0x00000800" or
s = "0x00001000" or
s = "0x00002000" or
s = "0x00004000" or
s = "0x00008000" or
s = "0x00010000" or
s = "0x00020000" or
s = "0x00040000" or
s = "0x00080000" or
s = "0x00100000" or
s = "0x00200000" or
s = "0x00400000" or
s = "0x00800000" or
s = "0x01000000" or
s = "0x02000000" or
s = "0x04000000" or
s = "0x08000000" or
s = "0x10000000" or
s = "0x20000000" or
s = "0x40000000" or
s = "0x80000000" or
// Popular powers of two, minus one (32-bit hex)
s = "0x00000001" or
s = "0x00000003" or
s = "0x00000007" or
s = "0x0000000f" or
s = "0x0000001f" or
s = "0x0000003f" or
s = "0x0000007f" or
s = "0x000000ff" or
s = "0x000001ff" or
s = "0x000003ff" or
s = "0x000007ff" or
s = "0x00000fff" or
s = "0x00001fff" or
s = "0x00003fff" or
s = "0x00007fff" or
s = "0x0000ffff" or
s = "0x0001ffff" or
s = "0x0003ffff" or
s = "0x0007ffff" or
s = "0x000fffff" or
s = "0x001fffff" or
s = "0x003fffff" or
s = "0x007fffff" or
s = "0x00ffffff" or
s = "0x01ffffff" or
s = "0x03ffffff" or
s = "0x07ffffff" or
s = "0x0fffffff" or
s = "0x1fffffff" or
s = "0x3fffffff" or
s = "0x7fffffff" or
s = "0xffffffff" or
// Popular powers of two (16-bit hex)
s = "0x0001" or
s = "0x0002" or
s = "0x0004" or
s = "0x0008" or
s = "0x0010" or
s = "0x0020" or
s = "0x0040" or
s = "0x0080" or
s = "0x0100" or
s = "0x0200" or
s = "0x0400" or
s = "0x0800" or
s = "0x1000" or
s = "0x2000" or
s = "0x4000" or
s = "0x8000" or
// Popular powers of two, minus one (16-bit hex)
s = "0x0001" or
s = "0x0003" or
s = "0x0007" or
s = "0x000f" or
s = "0x001f" or
s = "0x003f" or
s = "0x007f" or
s = "0x00ff" or
s = "0x01ff" or
s = "0x03ff" or
s = "0x07ff" or
s = "0x0fff" or
s = "0x1fff" or
s = "0x3fff" or
s = "0x7fff" or
s = "0xffff" or
// Popular powers of two (8-bit hex)
s = "0x01" or
s = "0x02" or
s = "0x04" or
s = "0x08" or
s = "0x10" or
s = "0x20" or
s = "0x40" or
s = "0x80" or
// Popular powers of two, minus one (8-bit hex)
s = "0x01" or
s = "0x03" or
s = "0x07" or
s = "0x0f" or
s = "0x1f" or
s = "0x3f" or
s = "0x7f" or
s = "0xff" or
s = "0x00" or
// Powers of ten
s = "10" or
s = "100" or
s = "1000" or
s = "10000" or
s = "100000" or
s = "1000000" or
s = "10000000" or
s = "100000000" or
s = "1000000000"
s =
[
// Popular powers of two (decimal)
"16", "24", "32", "64", "128", "256", "512", "1024", "2048", "4096", "16384", "32768",
"65536", "1048576", "2147483648", "4294967296",
// Popular powers of two, minus one (decimal)
"15", "31", "63", "127", "255", "511", "1023", "2047", "4095", "16383", "32767", "65535",
"1048577", "2147483647", "4294967295",
// Popular powers of two (32-bit hex)
"0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", "0x00000020",
"0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", "0x00000800",
"0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", "0x00020000",
"0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", "0x00800000",
"0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", "0x20000000",
"0x40000000", "0x80000000",
// Popular powers of two, minus one (32-bit hex)
"0x00000001", "0x00000003", "0x00000007", "0x0000000f", "0x0000001f", "0x0000003f",
"0x0000007f", "0x000000ff", "0x000001ff", "0x000003ff", "0x000007ff", "0x00000fff",
"0x00001fff", "0x00003fff", "0x00007fff", "0x0000ffff", "0x0001ffff", "0x0003ffff",
"0x0007ffff", "0x000fffff", "0x001fffff", "0x003fffff", "0x007fffff", "0x00ffffff",
"0x01ffffff", "0x03ffffff", "0x07ffffff", "0x0fffffff", "0x1fffffff", "0x3fffffff",
"0x7fffffff", "0xffffffff",
// Popular powers of two (16-bit hex)
"0x0001", "0x0002", "0x0004", "0x0008", "0x0010", "0x0020", "0x0040", "0x0080", "0x0100",
"0x0200", "0x0400", "0x0800", "0x1000", "0x2000", "0x4000", "0x8000",
// Popular powers of two, minus one (16-bit hex)
"0x0001", "0x0003", "0x0007", "0x000f", "0x001f", "0x003f", "0x007f", "0x00ff", "0x01ff",
"0x03ff", "0x07ff", "0x0fff", "0x1fff", "0x3fff", "0x7fff", "0xffff",
// Popular powers of two (8-bit hex)
"0x01", "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80",
// Popular powers of two, minus one (8-bit hex)
"0x01", "0x03", "0x07", "0x0f", "0x1f", "0x3f", "0x7f", "0xff", "0x00",
// Powers of ten
"10", "100", "1000", "10000", "100000", "1000000", "10000000", "100000000", "1000000000"
]
}
predicate trivialIntValue(string s) {
@@ -235,10 +108,7 @@ predicate joiningStringTrivial(Literal lit) {
// understand (which is against the spirit of these queries).
stringLiteral(lit) and
exists(FunctionCall fc |
(
fc.getTarget().getName() = "operator+" or
fc.getTarget().getName() = "operator<<"
) and
fc.getTarget().getName() = ["operator+", "operator<<"] and
fc.getAnArgument().getAChild*() = lit
) and
lit.getValue().length() < 16

View File

@@ -59,14 +59,9 @@ class Options extends string {
predicate exits(Function f) {
f.getAnAttribute().hasName("noreturn")
or
exists(string name | f.hasGlobalOrStdName(name) |
name = "exit" or
name = "_exit" or
name = "abort" or
name = "__assert_fail" or
name = "longjmp" or
name = "__builtin_unreachable"
)
f.hasGlobalOrStdName([
"exit", "_exit", "abort", "__assert_fail", "longjmp", "__builtin_unreachable"
])
or
CustomOptions::exits(f) // old Options.qll
}

View File

@@ -21,15 +21,7 @@ class Initialization extends Function {
}
class Allocation extends FunctionCall {
Allocation() {
exists(string name | name = this.getTarget().getName() |
name = "malloc" or
name = "calloc" or
name = "alloca" or
name = "sbrk" or
name = "valloc"
)
}
Allocation() { this.getTarget().getName() = ["malloc", "calloc", "alloca", "sbrk", "valloc"] }
}
from Function f, Allocation a

View File

@@ -13,13 +13,8 @@ import cpp
class ForbiddenCall extends FunctionCall {
ForbiddenCall() {
exists(string name | name = this.getTarget().getName() |
name = "task_delay" or
name = "taskDelay" or
name = "sleep" or
name = "nanosleep" or
name = "clock_nanosleep"
)
this.getTarget().getName() =
["task_delay", "taskDelay", "sleep", "nanosleep", "clock_nanosleep"]
}
}

View File

@@ -6,12 +6,7 @@ import cpp
class SemaphoreCreation extends FunctionCall {
SemaphoreCreation() {
exists(string name | name = this.getTarget().getName() |
name = "semBCreate" or
name = "semMCreate" or
name = "semCCreate" or
name = "semRWCreate"
)
this.getTarget().getName() = ["semBCreate", "semMCreate", "semCCreate", "semRWCreate"]
}
Variable getSemaphore() { result.getAnAccess() = this.getParent().(Assignment).getLValue() }
@@ -72,11 +67,7 @@ class SemaphoreGive extends UnlockOperation {
}
class LockingPrimitive extends FunctionCall, LockOperation {
LockingPrimitive() {
exists(string name | name = this.getTarget().getName() |
name = "taskLock" or name = "intLock" or name = "taskRtpLock"
)
}
LockingPrimitive() { this.getTarget().getName() = ["taskLock", "intLock", "taskRtpLock"] }
override Function getLocked() { result = this.getTarget() }
@@ -89,11 +80,7 @@ class LockingPrimitive extends FunctionCall, LockOperation {
}
class UnlockingPrimitive extends FunctionCall, UnlockOperation {
UnlockingPrimitive() {
exists(string name | name = this.getTarget().getName() |
name = "taskUnlock" or name = "intUnlock" or name = "taskRtpUnlock"
)
}
UnlockingPrimitive() { this.getTarget().getName() = ["taskUnlock", "intUnlock", "taskRtpUnlock"] }
Function getLocked() { result = getMatchingLock().getLocked() }

View File

@@ -12,18 +12,7 @@
import cpp
predicate allowedTypedefs(TypedefType t) {
exists(string name | name = t.getName() |
name = "I64" or
name = "U64" or
name = "I32" or
name = "U32" or
name = "I16" or
name = "U16" or
name = "I8" or
name = "U8" or
name = "F64" or
name = "F32"
)
t.getName() = ["I64", "U64", "I32", "U32", "I16", "U16", "I8", "U8", "F64", "F32"]
}
/**

View File

@@ -5,8 +5,8 @@ import cpp
*/
class Task extends Function {
Task() {
exists(FunctionCall taskCreate, string name | name = "taskCreate" or name = "taskSpawn" |
name = taskCreate.getTarget().getName() and
exists(FunctionCall taskCreate |
taskCreate.getTarget().getName() = ["taskCreate", "taskSpawn"] and
this = taskCreate.getArgument(4).(AddressOfExpr).getAddressable()
)
}

View File

@@ -13,38 +13,17 @@ import cpp
import semmle.code.cpp.dataflow.DataFlow
predicate whitelist(Function f) {
exists(string fName |
fName = f.getName() and
(
fName = "ceil" or
fName = "ceilf" or
fName = "ceill" or
fName = "floor" or
fName = "floorf" or
fName = "floorl" or
fName = "nearbyint" or
fName = "nearbyintf" or
fName = "nearbyintl" or
fName = "rint" or
fName = "rintf" or
fName = "rintl" or
fName = "round" or
fName = "roundf" or
fName = "roundl" or
fName = "trunc" or
fName = "truncf" or
fName = "truncl" or
fName.matches("__builtin_%")
)
)
f.getName() =
[
"ceil", "ceilf", "ceill", "floor", "floorf", "floorl", "nearbyint", "nearbyintf",
"nearbyintl", "rint", "rintf", "rintl", "round", "roundf", "roundl", "trunc", "truncf",
"truncl"
] or
f.getName().matches("__builtin_%")
}
predicate whitelistPow(FunctionCall fc) {
(
fc.getTarget().getName() = "pow" or
fc.getTarget().getName() = "powf" or
fc.getTarget().getName() = "powl"
) and
fc.getTarget().getName() = ["pow", "powf", "powl"] and
exists(float value |
value = fc.getArgument(0).getValue().toFloat() and
(value.floor() - value).abs() < 0.001

View File

@@ -326,52 +326,35 @@ class InitializationFunction extends Function {
// Return value is not a success code but the output functions never fail.
name.matches("_Interlocked%")
or
// Functions that never fail, according to MSDN.
name = "QueryPerformanceCounter"
or
name = "QueryPerformanceFrequency"
or
// Functions that never fail post-Vista, according to MSDN.
name = "InitializeCriticalSectionAndSpinCount"
or
// `rand_s` writes 0 to a non-null argument if it fails, according to MSDN.
name = "rand_s"
or
// IntersectRect initializes the argument regardless of whether the input intersects
name = "IntersectRect"
or
name = "SetRect"
or
name = "UnionRect"
or
// These functions appears to have an incorrect CFG, which leads to false positives
name = "PhysicalToLogicalDPIPoint"
or
name = "LogicalToPhysicalDPIPoint"
or
// Sets NtProductType to default on error
name = "RtlGetNtProductType"
or
// Our CFG is not sophisticated enough to detect that the argument is always initialized
name = "StringCchLengthA"
or
// All paths init the argument, and always returns SUCCESS.
name = "RtlUnicodeToMultiByteSize"
or
// All paths init the argument, and always returns SUCCESS.
name = "RtlMultiByteToUnicodeSize"
or
// All paths init the argument, and always returns SUCCESS.
name = "RtlUnicodeToMultiByteN"
or
// Always initializes argument
name = "RtlGetFirstRange"
or
// Destination range is zeroed out on failure, assuming first two parameters are valid
name = "memcpy_s"
or
// This zeroes the memory unconditionally
name = "SeCreateAccessState"
name =
[
// Functions that never fail, according to MSDN.
"QueryPerformanceCounter", "QueryPerformanceFrequency",
// Functions that never fail post-Vista, according to MSDN.
"InitializeCriticalSectionAndSpinCount",
// `rand_s` writes 0 to a non-null argument if it fails, according to MSDN.
"rand_s",
// IntersectRect initializes the argument regardless of whether the input intersects
"IntersectRect", "SetRect", "UnionRect",
// These functions appears to have an incorrect CFG, which leads to false positives
"PhysicalToLogicalDPIPoint", "LogicalToPhysicalDPIPoint",
// Sets NtProductType to default on error
"RtlGetNtProductType",
// Our CFG is not sophisticated enough to detect that the argument is always initialized
"StringCchLengthA",
// All paths init the argument, and always returns SUCCESS.
"RtlUnicodeToMultiByteSize",
// All paths init the argument, and always returns SUCCESS.
"RtlMultiByteToUnicodeSize",
// All paths init the argument, and always returns SUCCESS.
"RtlUnicodeToMultiByteN",
// Always initializes argument
"RtlGetFirstRange",
// Destination range is zeroed out on failure, assuming first two parameters are valid
"memcpy_s",
// This zeroes the memory unconditionally
"SeCreateAccessState"
]
)
}
}

View File

@@ -140,12 +140,9 @@ class FopenCreationExpr extends FileCreationExpr {
class FopensCreationExpr extends FileCreationExpr {
FopensCreationExpr() {
exists(string name | name = this.getTarget().getName() |
name = "fopen_s" or
name = "_wfopen_s"
) and
this.getTarget().getName() = ["fopen_s", "_wfopen_s"] and
exists(string mode |
(mode = "w" or mode = "a") and
mode = ["w", "a"] and
this.getArgument(2).getValue().matches(mode + "%")
)
}

View File

@@ -13,9 +13,10 @@ int main(int argc, char **argv)
char buf1[10];
scanf("%s", buf1);
// GOOD, length is specified. The length should be one less than the size of the buffer, since the last character is the NULL terminator.
char buf2[10];
sscanf(buf2, "%9s");
// GOOD, length is specified. The length should be one less than the size of the destination buffer, since the last character is the NULL terminator.
char buf2[20];
char buf3[10];
sscanf(buf2, "%9s", buf3);
// BAD, do not use scanf without specifying a length first
char file[10];

View File

@@ -363,20 +363,8 @@ class File extends Container, @file {
*/
class HeaderFile extends File {
HeaderFile() {
exists(string ext | ext = this.getExtension().toLowerCase() |
ext = "h" or
ext = "r" or
/* --- */ ext = "hpp" or
ext = "hxx" or
ext = "h++" or
ext = "hh" or
ext = "hp" or
ext = "tcc" or
ext = "tpp" or
ext = "txx" or
ext = "t++"
/* --- --- */
)
this.getExtension().toLowerCase() =
["h", "r", "hpp", "hxx", "h++", "hh", "hp", "tcc", "tpp", "txx", "t++"]
or
not exists(this.getExtension()) and
exists(Include i | i.getIncludedFile() = this)
@@ -406,7 +394,7 @@ class HeaderFile extends File {
* `File.compiledAsC`.
*/
class CFile extends File {
CFile() { exists(string ext | ext = this.getExtension().toLowerCase() | ext = "c" or ext = "i") }
CFile() { this.getExtension().toLowerCase() = ["c", "i"] }
override string getAPrimaryQlClass() { result = "CFile" }
}
@@ -419,21 +407,10 @@ class CFile extends File {
*/
class CppFile extends File {
CppFile() {
exists(string ext | ext = this.getExtension().toLowerCase() |
/* --- */ ext = "cpp" or
ext = "cxx" or
ext = "c++" or
ext = "cc" or
ext = "cp" or
ext = "icc" or
ext = "ipp" or
ext = "ixx" or
ext = "i++" or
ext = "ii"
/* --- */
// Note: .C files are indistinguishable from .c files on some
// file systems, so we just treat them as CFile's.
)
this.getExtension().toLowerCase() =
["cpp", "cxx", "c++", "cc", "cp", "icc", "ipp", "ixx", "i++", "ii"]
// Note: .C files are indistinguishable from .c files on some
// file systems, so we just treat them as CFile's.
}
override string getAPrimaryQlClass() { result = "CppFile" }

View File

@@ -445,50 +445,15 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
// ... and likewise for destructors.
this.(Destructor).getADestruction().mayBeGloballyImpure()
else
not exists(string name | this.hasGlobalOrStdName(name) |
// Unless it's a function that we know is side-effect-free, it may
// have side-effects.
name = "strcmp" or
name = "wcscmp" or
name = "_mbscmp" or
name = "strlen" or
name = "wcslen" or
name = "_mbslen" or
name = "_mbslen_l" or
name = "_mbstrlen" or
name = "_mbstrlen_l" or
name = "strnlen" or
name = "strnlen_s" or
name = "wcsnlen" or
name = "wcsnlen_s" or
name = "_mbsnlen" or
name = "_mbsnlen_l" or
name = "_mbstrnlen" or
name = "_mbstrnlen_l" or
name = "strncmp" or
name = "wcsncmp" or
name = "_mbsncmp" or
name = "_mbsncmp_l" or
name = "strchr" or
name = "memchr" or
name = "wmemchr" or
name = "memcmp" or
name = "wmemcmp" or
name = "_memicmp" or
name = "_memicmp_l" or
name = "feof" or
name = "isdigit" or
name = "isxdigit" or
name = "abs" or
name = "fabs" or
name = "labs" or
name = "floor" or
name = "ceil" or
name = "atoi" or
name = "atol" or
name = "atoll" or
name = "atof"
)
// Unless it's a function that we know is side-effect-free, it may
// have side-effects.
not this.hasGlobalOrStdName([
"strcmp", "wcscmp", "_mbscmp", "strlen", "wcslen", "_mbslen", "_mbslen_l", "_mbstrlen",
"_mbstrlen_l", "strnlen", "strnlen_s", "wcsnlen", "wcsnlen_s", "_mbsnlen", "_mbsnlen_l",
"_mbstrnlen", "_mbstrnlen_l", "strncmp", "wcsncmp", "_mbsncmp", "_mbsncmp_l", "strchr",
"memchr", "wmemchr", "memcmp", "wmemcmp", "_memicmp", "_memicmp_l", "feof", "isdigit",
"isxdigit", "abs", "fabs", "labs", "floor", "ceil", "atoi", "atol", "atoll", "atof"
])
}
/**

View File

@@ -385,7 +385,7 @@ private class DumpFunction extends DumpDeclaration, Function {
private string getACVQualifier() {
result = getASpecifier().getName() and
(result = "const" or result = "volatile")
result = ["const", "volatile"]
}
private string getDeclaratorSuffix() {

View File

@@ -14,11 +14,7 @@ class PackedTimeType extends Type {
}
}
private predicate timeType(string typeName) {
typeName = "_SYSTEMTIME" or
typeName = "SYSTEMTIME" or
typeName = "tm"
}
private predicate timeType(string typeName) { typeName = ["_SYSTEMTIME", "SYSTEMTIME", "tm"] }
/**
* A type that is used to represent times and dates in an 'unpacked' form, that is,

View File

@@ -13,7 +13,7 @@ import Dereferenced
* predicates that implement this analysis.
*/
abstract class DataflowAnnotation extends string {
DataflowAnnotation() { this = "pointer-null" or this = "pointer-valid" }
DataflowAnnotation() { this = ["pointer-null", "pointer-valid"] }
/** Holds if this annotation is the default annotation. */
abstract predicate isDefault();
@@ -98,7 +98,7 @@ abstract class DataflowAnnotation extends string {
* respectively.
*/
class NullnessAnnotation extends DataflowAnnotation {
NullnessAnnotation() { this = "pointer-null" or this = "pointer-valid" }
NullnessAnnotation() { this = ["pointer-null", "pointer-valid"] }
override predicate isDefault() { this = "pointer-valid" }

View File

@@ -36,24 +36,12 @@ private predicate predictableInstruction(Instruction instr) {
* library's `returnArgument` predicate.
*/
predicate predictableOnlyFlow(string name) {
name = "strcasestr" or
name = "strchnul" or
name = "strchr" or
name = "strchrnul" or
name = "strcmp" or
name = "strcspn" or
name = "strncmp" or
name = "strndup" or
name = "strnlen" or
name = "strrchr" or
name = "strspn" or
name = "strstr" or
name = "strtod" or
name = "strtof" or
name = "strtol" or
name = "strtoll" or
name = "strtoq" or
name = "strtoul"
name =
[
"strcasestr", "strchnul", "strchr", "strchrnul", "strcmp", "strcspn", "strncmp", "strndup",
"strnlen", "strrchr", "strspn", "strstr", "strtod", "strtof", "strtol", "strtoll", "strtoq",
"strtoul"
]
}
private DataFlow::Node getNodeForSource(Expr source) {

View File

@@ -14,95 +14,58 @@ private class MallocAllocationFunction extends AllocationFunction {
int sizeArg;
MallocAllocationFunction() {
exists(string name |
hasGlobalOrStdName(name) and
// malloc(size)
(name = "malloc" and sizeArg = 0)
or
hasGlobalName(name) and
(
// ExAllocatePool(type, size)
name = "ExAllocatePool" and sizeArg = 1
or
// ExAllocatePool(type, size, tag)
name = "ExAllocatePoolWithTag" and sizeArg = 1
or
// ExAllocatePoolWithTagPriority(type, size, tag, priority)
name = "ExAllocatePoolWithTagPriority" and sizeArg = 1
or
// ExAllocatePoolWithQuota(type, size)
name = "ExAllocatePoolWithQuota" and sizeArg = 1
or
// ExAllocatePoolWithQuotaTag(type, size, tag)
name = "ExAllocatePoolWithQuotaTag" and sizeArg = 1
or
// IoAllocateMdl(address, size, flag, flag, irp)
name = "IoAllocateMdl" and sizeArg = 1
or
// IoAllocateErrorLogEntry(object, size)
name = "IoAllocateErrorLogEntry" and sizeArg = 1
or
// MmAllocateContiguousMemory(size, maxaddress)
name = "MmAllocateContiguousMemory" and sizeArg = 0
or
// MmAllocateContiguousNodeMemory(size, minaddress, maxaddress, bound, flag, prefer)
name = "MmAllocateContiguousNodeMemory" and sizeArg = 0
or
// MmAllocateContiguousMemorySpecifyCache(size, minaddress, maxaddress, bound, type)
name = "MmAllocateContiguousMemorySpecifyCache" and sizeArg = 0
or
// MmAllocateContiguousMemorySpecifyCacheNode(size, minaddress, maxaddress, bound, type, prefer)
name = "MmAllocateContiguousMemorySpecifyCacheNode" and sizeArg = 0
or
// MmAllocateNonCachedMemory(size)
name = "MmAllocateNonCachedMemory" and sizeArg = 0
or
// MmAllocateMappingAddress(size, tag)
name = "MmAllocateMappingAddress" and sizeArg = 0
or
// MmAllocatePagesForMdl(minaddress, maxaddress, skip, size)
name = "MmAllocatePagesForMdl" and sizeArg = 3
or
// MmAllocatePagesForMdlEx(minaddress, maxaddress, skip, size, type, flags)
name = "MmAllocatePagesForMdlEx" and sizeArg = 3
or
// MmAllocateNodePagesForMdlEx(minaddress, maxaddress, skip, size, type, prefer, flags)
name = "MmAllocateNodePagesForMdlEx" and sizeArg = 3
or
// LocalAlloc(flags, size)
name = "LocalAlloc" and sizeArg = 1
or
// GlobalAlloc(flags, size)
name = "GlobalAlloc" and sizeArg = 1
or
// HeapAlloc(heap, flags, size)
name = "HeapAlloc" and sizeArg = 2
or
// VirtualAlloc(address, size, type, flag)
name = "VirtualAlloc" and sizeArg = 1
or
// CoTaskMemAlloc(size)
name = "CoTaskMemAlloc" and sizeArg = 0
or
// kmem_alloc(size, flags)
name = "kmem_alloc" and sizeArg = 0
or
// kmem_zalloc(size, flags)
name = "kmem_zalloc" and sizeArg = 0
or
// CRYPTO_malloc(size_t num, const char *file, int line)
name = "CRYPTO_malloc" and sizeArg = 0
or
// CRYPTO_zalloc(size_t num, const char *file, int line)
name = "CRYPTO_zalloc" and sizeArg = 0
or
// CRYPTO_secure_malloc(size_t num, const char *file, int line)
name = "CRYPTO_secure_malloc" and sizeArg = 0
or
// CRYPTO_secure_zalloc(size_t num, const char *file, int line)
name = "CRYPTO_secure_zalloc" and sizeArg = 0
)
)
// --- C library allocation
hasGlobalOrStdName("malloc") and // malloc(size)
sizeArg = 0
or
hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"MmAllocateContiguousMemory", // MmAllocateContiguousMemory(size, maxaddress)
"MmAllocateContiguousNodeMemory", // MmAllocateContiguousNodeMemory(size, minaddress, maxaddress, bound, flag, prefer)
"MmAllocateContiguousMemorySpecifyCache", // MmAllocateContiguousMemorySpecifyCache(size, minaddress, maxaddress, bound, type)
"MmAllocateContiguousMemorySpecifyCacheNode", // MmAllocateContiguousMemorySpecifyCacheNode(size, minaddress, maxaddress, bound, type, prefer)
"MmAllocateNonCachedMemory", // MmAllocateNonCachedMemory(size)
"MmAllocateMappingAddress", // MmAllocateMappingAddress(size, tag)
// --- Windows COM allocation
"CoTaskMemAlloc", // CoTaskMemAlloc(size)
// --- Solaris/BSD kernel memory allocator
"kmem_alloc", // kmem_alloc(size, flags)
"kmem_zalloc", // kmem_zalloc(size, flags)
// --- OpenSSL memory allocation
"CRYPTO_malloc", // CRYPTO_malloc(size_t num, const char *file, int line)
"CRYPTO_zalloc", // CRYPTO_zalloc(size_t num, const char *file, int line)
"CRYPTO_secure_malloc", // CRYPTO_secure_malloc(size_t num, const char *file, int line)
"CRYPTO_secure_zalloc" // CRYPTO_secure_zalloc(size_t num, const char *file, int line)
]) and
sizeArg = 0
or
hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"ExAllocatePool", // ExAllocatePool(type, size)
"ExAllocatePoolWithTag", // ExAllocatePool(type, size, tag)
"ExAllocatePoolWithTagPriority", // ExAllocatePoolWithTagPriority(type, size, tag, priority)
"ExAllocatePoolWithQuota", // ExAllocatePoolWithQuota(type, size)
"ExAllocatePoolWithQuotaTag", // ExAllocatePoolWithQuotaTag(type, size, tag)
"IoAllocateMdl", // IoAllocateMdl(address, size, flag, flag, irp)
"IoAllocateErrorLogEntry", // IoAllocateErrorLogEntry(object, size)
// --- Windows Global / Local legacy allocation
"LocalAlloc", // LocalAlloc(flags, size)
"GlobalAlloc", // GlobalAlloc(flags, size)
// --- Windows System Services allocation
"VirtualAlloc" // VirtualAlloc(address, size, type, flag)
]) and
sizeArg = 1
or
hasGlobalName(["HeapAlloc"]) and // HeapAlloc(heap, flags, size)
sizeArg = 2
or
hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"MmAllocatePagesForMdl", // MmAllocatePagesForMdl(minaddress, maxaddress, skip, size)
"MmAllocatePagesForMdlEx", // MmAllocatePagesForMdlEx(minaddress, maxaddress, skip, size, type, flags)
"MmAllocateNodePagesForMdlEx" // MmAllocateNodePagesForMdlEx(minaddress, maxaddress, skip, size, type, prefer, flags)
]) and
sizeArg = 3
}
override int getSizeArg() { result = sizeArg }
@@ -116,16 +79,12 @@ private class AllocaAllocationFunction extends AllocationFunction {
int sizeArg;
AllocaAllocationFunction() {
exists(string name |
hasGlobalName(name) and
(
// alloca(size)
name = "alloca" and sizeArg = 0
or
// __builtin_alloca(size)
name = "__builtin_alloca" and sizeArg = 0
)
)
hasGlobalName([
// --- stack allocation
"alloca", // // alloca(size)
"__builtin_alloca" // __builtin_alloca(size)
]) and
sizeArg = 0
}
override int getSizeArg() { result = sizeArg }
@@ -142,11 +101,10 @@ private class CallocAllocationFunction extends AllocationFunction {
int multArg;
CallocAllocationFunction() {
exists(string name |
hasGlobalOrStdName(name) and
// calloc(num, size)
(name = "calloc" and sizeArg = 1 and multArg = 0)
)
// --- C library allocation
hasGlobalOrStdName("calloc") and // calloc(num, size)
sizeArg = 1 and
multArg = 0
}
override int getSizeArg() { result = sizeArg }
@@ -163,29 +121,26 @@ private class ReallocAllocationFunction extends AllocationFunction {
int reallocArg;
ReallocAllocationFunction() {
exists(string name |
hasGlobalOrStdName(name) and
// realloc(ptr, size)
(name = "realloc" and sizeArg = 1 and reallocArg = 0)
or
hasGlobalName(name) and
(
// LocalReAlloc(ptr, size, flags)
name = "LocalReAlloc" and sizeArg = 1 and reallocArg = 0
or
// GlobalReAlloc(ptr, size, flags)
name = "GlobalReAlloc" and sizeArg = 1 and reallocArg = 0
or
// HeapReAlloc(heap, flags, ptr, size)
name = "HeapReAlloc" and sizeArg = 3 and reallocArg = 2
or
// CoTaskMemRealloc(ptr, size)
name = "CoTaskMemRealloc" and sizeArg = 1 and reallocArg = 0
or
// CRYPTO_realloc(void *addr, size_t num, const char *file, int line);
name = "CRYPTO_realloc" and sizeArg = 1 and reallocArg = 0
)
)
// --- C library allocation
hasGlobalOrStdName("realloc") and // realloc(ptr, size)
sizeArg = 1 and
reallocArg = 0
or
hasGlobalName([
// --- Windows Global / Local legacy allocation
"LocalReAlloc", // LocalReAlloc(ptr, size, flags)
"GlobalReAlloc", // GlobalReAlloc(ptr, size, flags)
// --- Windows COM allocation
"CoTaskMemRealloc", // CoTaskMemRealloc(ptr, size)
// --- OpenSSL memory allocation
"CRYPTO_realloc" // CRYPTO_realloc(void *addr, size_t num, const char *file, int line)
]) and
sizeArg = 1 and
reallocArg = 0
or
hasGlobalName("HeapReAlloc") and // HeapReAlloc(heap, flags, ptr, size)
sizeArg = 3 and
reallocArg = 2
}
override int getSizeArg() { result = sizeArg }
@@ -199,40 +154,20 @@ private class ReallocAllocationFunction extends AllocationFunction {
*/
private class SizelessAllocationFunction extends AllocationFunction {
SizelessAllocationFunction() {
exists(string name |
hasGlobalName(name) and
(
// ExAllocateFromLookasideListEx(list)
name = "ExAllocateFromLookasideListEx"
or
// ExAllocateFromPagedLookasideList(list)
name = "ExAllocateFromPagedLookasideList"
or
// ExAllocateFromNPagedLookasideList(list)
name = "ExAllocateFromNPagedLookasideList"
or
// ExAllocateTimer(callback, context, attributes)
name = "ExAllocateTimer"
or
// IoAllocateWorkItem(object)
name = "IoAllocateWorkItem"
or
// MmMapLockedPagesWithReservedMapping(address, tag, list, type)
name = "MmMapLockedPagesWithReservedMapping"
or
// MmMapLockedPages(list, mode)
name = "MmMapLockedPages"
or
// MmMapLockedPagesSpecifyCache(list, mode, type, address, flag, flag)
name = "MmMapLockedPagesSpecifyCache"
or
// pool_get(pool, flags)
name = "pool_get"
or
// pool_cache_get(pool, flags)
name = "pool_cache_get"
)
)
hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"ExAllocateFromLookasideListEx", // ExAllocateFromLookasideListEx(list)
"ExAllocateFromPagedLookasideList", // ExAllocateFromPagedLookasideList(list)
"ExAllocateFromNPagedLookasideList", // ExAllocateFromNPagedLookasideList(list)
"ExAllocateTimer", // ExAllocateTimer(callback, context, attributes)
"IoAllocateWorkItem", // IoAllocateWorkItem(object)
"MmMapLockedPagesWithReservedMapping", // MmMapLockedPagesWithReservedMapping(address, tag, list, type)
"MmMapLockedPages", // MmMapLockedPages(list, mode)
"MmMapLockedPagesSpecifyCache", // MmMapLockedPagesSpecifyCache(list, mode, type, address, flag, flag)
// --- NetBSD pool manager
"pool_get", // pool_get(pool, flags)
"pool_cache_get" // pool_cache_get(pool, flags)
])
}
}

View File

@@ -13,77 +13,43 @@ private class StandardDeallocationFunction extends DeallocationFunction {
int freedArg;
StandardDeallocationFunction() {
exists(string name |
hasGlobalName(name) and
(
name = "free" and freedArg = 0
or
name = "realloc" and freedArg = 0
or
name = "CRYPTO_free" and freedArg = 0
or
name = "CRYPTO_secure_free" and freedArg = 0
)
or
hasGlobalOrStdName(name) and
(
name = "ExFreePoolWithTag" and freedArg = 0
or
name = "ExFreeToLookasideListEx" and freedArg = 1
or
name = "ExFreeToPagedLookasideList" and freedArg = 1
or
name = "ExFreeToNPagedLookasideList" and freedArg = 1
or
name = "ExDeleteTimer" and freedArg = 0
or
name = "IoFreeMdl" and freedArg = 0
or
name = "IoFreeWorkItem" and freedArg = 0
or
name = "IoFreeErrorLogEntry" and freedArg = 0
or
name = "MmFreeContiguousMemory" and freedArg = 0
or
name = "MmFreeContiguousMemorySpecifyCache" and freedArg = 0
or
name = "MmFreeNonCachedMemory" and freedArg = 0
or
name = "MmFreeMappingAddress" and freedArg = 0
or
name = "MmFreePagesFromMdl" and freedArg = 0
or
name = "MmUnmapReservedMapping" and freedArg = 0
or
name = "MmUnmapLockedPages" and freedArg = 0
or
name = "LocalFree" and freedArg = 0
or
name = "GlobalFree" and freedArg = 0
or
name = "HeapFree" and freedArg = 2
or
name = "VirtualFree" and freedArg = 0
or
name = "CoTaskMemFree" and freedArg = 0
or
name = "SysFreeString" and freedArg = 0
or
name = "LocalReAlloc" and freedArg = 0
or
name = "GlobalReAlloc" and freedArg = 0
or
name = "HeapReAlloc" and freedArg = 2
or
name = "CoTaskMemRealloc" and freedArg = 0
or
name = "kmem_free" and freedArg = 0
or
name = "pool_put" and freedArg = 1
or
name = "pool_cache_put" and freedArg = 1
)
)
hasGlobalName([
// --- C library allocation
"free", "realloc",
// --- OpenSSL memory allocation
"CRYPTO_free", "CRYPTO_secure_free"
]) and
freedArg = 0
or
hasGlobalOrStdName([
// --- Windows Memory Management for Windows Drivers
"ExFreePoolWithTag", "ExDeleteTimer", "IoFreeMdl", "IoFreeWorkItem", "IoFreeErrorLogEntry",
"MmFreeContiguousMemory", "MmFreeContiguousMemorySpecifyCache", "MmFreeNonCachedMemory",
"MmFreeMappingAddress", "MmFreePagesFromMdl", "MmUnmapReservedMapping",
"MmUnmapLockedPages",
// --- Windows Global / Local legacy allocation
"LocalFree", "GlobalFree", "LocalReAlloc", "GlobalReAlloc",
// --- Windows System Services allocation
"VirtualFree",
// --- Windows COM allocation
"CoTaskMemFree", "CoTaskMemRealloc",
// --- Windows Automation
"SysFreeString",
// --- Solaris/BSD kernel memory allocator
"kmem_free"
]) and
freedArg = 0
or
hasGlobalOrStdName([
// --- Windows Memory Management for Windows Drivers
"ExFreeToLookasideListEx", "ExFreeToPagedLookasideList", "ExFreeToNPagedLookasideList",
// --- NetBSD pool manager
"pool_put", "pool_cache_put"
]) and
freedArg = 1
or
hasGlobalOrStdName(["HeapFree", "HeapReAlloc"]) and
freedArg = 2
}
override int getFreedArg() { result = freedArg }

View File

@@ -15,13 +15,8 @@ import semmle.code.cpp.models.interfaces.SideEffect
private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunction,
SideEffectFunction {
MemsetFunction() {
hasGlobalName("memset") or
hasGlobalName("wmemset") or
hasGlobalName("bzero") or
hasGlobalName("__builtin_memset") or
hasGlobalName("__builtin_memset_chk") or
hasQualifiedName("std", "memset") or
hasQualifiedName("std", "wmemset")
hasGlobalName(["memset", "wmemset", "bzero", "__builtin_memset", "__builtin_memset_chk"]) or
hasQualifiedName("std", ["memset", "wmemset"])
}
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }

View File

@@ -15,11 +15,8 @@ private class Printf extends FormattingFunction, AliasFunction {
Printf() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdName("printf") or
hasGlobalName("printf_s") or
hasGlobalOrStdName("wprintf") or
hasGlobalName("wprintf_s") or
hasGlobalName("g_printf")
hasGlobalOrStdName(["printf", "wprintf"]) or
hasGlobalName(["printf_s", "wprintf_s", "g_printf"])
) and
not exists(getDefinition().getFile().getRelativePath())
}
@@ -47,8 +44,7 @@ private class Fprintf extends FormattingFunction {
Fprintf() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdName("fprintf") or
hasGlobalOrStdName("fwprintf") or
hasGlobalOrStdName(["fprintf", "fwprintf"]) or
hasGlobalName("g_fprintf")
) and
not exists(getDefinition().getFile().getRelativePath())
@@ -68,26 +64,18 @@ private class Sprintf extends FormattingFunction {
Sprintf() {
this instanceof TopLevelFunction and
(
// sprintf(dst, format, args...)
hasGlobalOrStdName("sprintf")
hasGlobalOrStdName([
"sprintf", // sprintf(dst, format, args...)
"wsprintf" // wsprintf(dst, format, args...)
])
or
// _sprintf_l(dst, format, locale, args...)
hasGlobalName("_sprintf_l")
or
// __swprintf_l(dst, format, locale, args...)
hasGlobalName("__swprintf_l")
or
// wsprintf(dst, format, args...)
hasGlobalOrStdName("wsprintf")
or
// g_strdup_printf(format, ...)
hasGlobalName("g_strdup_printf")
or
// g_sprintf(dst, format, ...)
hasGlobalName("g_sprintf")
or
// __builtin___sprintf_chk(dst, flag, os, format, ...)
hasGlobalName("__builtin___sprintf_chk")
hasGlobalName([
"_sprintf_l", // _sprintf_l(dst, format, locale, args...)
"__swprintf_l", // __swprintf_l(dst, format, locale, args...)
"g_strdup_printf", // g_strdup_printf(format, ...)
"g_sprintf", // g_sprintf(dst, format, ...)
"__builtin___sprintf_chk" // __builtin___sprintf_chk(dst, flag, os, format, ...)
])
) and
not exists(getDefinition().getFile().getRelativePath())
}
@@ -106,8 +94,7 @@ private class Sprintf extends FormattingFunction {
or
hasGlobalName("__builtin___sprintf_chk") and result = 3
or
getName() != "g_strdup_printf" and
getName() != "__builtin___sprintf_chk" and
not getName() = ["g_strdup_printf", "__builtin___sprintf_chk"] and
result = 1
}
@@ -129,26 +116,18 @@ private class SnprintfImpl extends Snprintf {
SnprintfImpl() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdName("snprintf") or // C99 defines snprintf
hasGlobalOrStdName("swprintf") or // The s version of wide-char printf is also always the n version
hasGlobalOrStdName([
"snprintf", // C99 defines snprintf
"swprintf" // The s version of wide-char printf is also always the n version
])
or
// Microsoft has _snprintf as well as several other variations
hasGlobalName("sprintf_s") or
hasGlobalName("snprintf_s") or
hasGlobalName("swprintf_s") or
hasGlobalName("_snprintf") or
hasGlobalName("_snprintf_s") or
hasGlobalName("_snprintf_l") or
hasGlobalName("_snprintf_s_l") or
hasGlobalName("_snwprintf") or
hasGlobalName("_snwprintf_s") or
hasGlobalName("_snwprintf_l") or
hasGlobalName("_snwprintf_s_l") or
hasGlobalName("_sprintf_s_l") or
hasGlobalName("_swprintf_l") or
hasGlobalName("_swprintf_s_l") or
hasGlobalName("g_snprintf") or
hasGlobalName("wnsprintf") or
hasGlobalName("__builtin___snprintf_chk")
hasGlobalName([
"sprintf_s", "snprintf_s", "swprintf_s", "_snprintf", "_snprintf_s", "_snprintf_l",
"_snprintf_s_l", "_snwprintf", "_snwprintf_s", "_snwprintf_l", "_snwprintf_s_l",
"_sprintf_s_l", "_swprintf_l", "_swprintf_s_l", "g_snprintf", "wnsprintf",
"__builtin___snprintf_chk"
])
) and
not exists(getDefinition().getFile().getRelativePath())
}
@@ -186,9 +165,7 @@ private class SnprintfImpl extends Snprintf {
override predicate returnsFullFormatLength() {
(
hasGlobalOrStdName("snprintf") or
hasGlobalName("g_snprintf") or
hasGlobalName("__builtin___snprintf_chk") or
hasGlobalName("snprintf_s")
hasGlobalName(["g_snprintf", "__builtin___snprintf_chk", "snprintf_s"])
) and
not exists(getDefinition().getFile().getRelativePath())
}
@@ -202,16 +179,10 @@ private class SnprintfImpl extends Snprintf {
private class StringCchPrintf extends FormattingFunction {
StringCchPrintf() {
this instanceof TopLevelFunction and
(
hasGlobalName("StringCchPrintf") or
hasGlobalName("StringCchPrintfEx") or
hasGlobalName("StringCchPrintf_l") or
hasGlobalName("StringCchPrintf_lEx") or
hasGlobalName("StringCbPrintf") or
hasGlobalName("StringCbPrintfEx") or
hasGlobalName("StringCbPrintf_l") or
hasGlobalName("StringCbPrintf_lEx")
) and
hasGlobalName([
"StringCchPrintf", "StringCchPrintfEx", "StringCchPrintf_l", "StringCchPrintf_lEx",
"StringCbPrintf", "StringCbPrintfEx", "StringCbPrintf_l", "StringCbPrintf_lEx"
]) and
not exists(getDefinition().getFile().getRelativePath())
}

View File

@@ -69,10 +69,8 @@ private class StdSequenceContainerData extends TaintFunction {
*/
private class StdSequenceContainerPush extends TaintFunction {
StdSequenceContainerPush() {
this.hasQualifiedName("std", "vector", "push_back") or
this.hasQualifiedName("std", "deque", ["push_back", "push_front"]) or
this.hasQualifiedName("std", "list", ["push_back", "push_front"]) or
this.hasQualifiedName("std", "forward_list", "push_front")
this.hasQualifiedName("std", ["vector", "deque", "list"], "push_back") or
this.hasQualifiedName("std", ["deque", "list", "forward_list"], "push_front")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -87,11 +85,8 @@ private class StdSequenceContainerPush extends TaintFunction {
*/
private class StdSequenceContainerFrontBack extends TaintFunction {
StdSequenceContainerFrontBack() {
this.hasQualifiedName("std", "array", ["front", "back"]) or
this.hasQualifiedName("std", "vector", ["front", "back"]) or
this.hasQualifiedName("std", "deque", ["front", "back"]) or
this.hasQualifiedName("std", "list", ["front", "back"]) or
this.hasQualifiedName("std", "forward_list", "front")
this.hasQualifiedName("std", ["array", "vector", "deque", "list", "forward_list"], "front") or
this.hasQualifiedName("std", ["array", "vector", "deque", "list"], "back")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -107,7 +102,7 @@ private class StdSequenceContainerFrontBack extends TaintFunction {
private class StdSequenceContainerInsert extends TaintFunction {
StdSequenceContainerInsert() {
this.hasQualifiedName("std", ["vector", "deque", "list"], "insert") or
this.hasQualifiedName("std", ["forward_list"], "insert_after")
this.hasQualifiedName("std", "forward_list", "insert_after")
}
/**

View File

@@ -13,15 +13,16 @@ import semmle.code.cpp.models.interfaces.SideEffect
*/
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction {
StrcatFunction() {
exists(string name | name = getName() |
name = "strcat" or // strcat(dst, src)
name = "strncat" or // strncat(dst, src, max_amount)
name = "wcscat" or // wcscat(dst, src)
name = "_mbscat" or // _mbscat(dst, src)
name = "wcsncat" or // wcsncat(dst, src, max_amount)
name = "_mbsncat" or // _mbsncat(dst, src, max_amount)
name = "_mbsncat_l" // _mbsncat_l(dst, src, max_amount, locale)
)
getName() =
[
"strcat", // strcat(dst, src)
"strncat", // strncat(dst, src, max_amount)
"wcscat", // wcscat(dst, src)
"_mbscat", // _mbscat(dst, src)
"wcsncat", // wcsncat(dst, src, max_amount)
"_mbsncat", // _mbsncat(dst, src, max_amount)
"_mbsncat_l" // _mbsncat_l(dst, src, max_amount, locale)
]
}
/**
@@ -45,20 +46,13 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(string name | name = getName() |
(
name = "strncat" or
name = "wcsncat" or
name = "_mbsncat" or
name = "_mbsncat_l"
) and
input.isParameter(2) and
output.isParameterDeref(0)
or
name = "_mbsncat_l" and
input.isParameter(3) and
output.isParameterDeref(0)
)
getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l"] and
input.isParameter(2) and
output.isParameterDeref(0)
or
getName() = "_mbsncat_l" and
input.isParameter(3) and
output.isParameterDeref(0)
or
input.isParameterDeref(0) and
output.isParameterDeref(0)

View File

@@ -13,25 +13,13 @@ import semmle.code.cpp.models.interfaces.Taint
*/
private class StrdupFunction extends AllocationFunction, ArrayFunction, DataFlowFunction {
StrdupFunction() {
exists(string name |
hasGlobalName(name) and
(
// strdup(str)
name = "strdup"
or
// wcsdup(str)
name = "wcsdup"
or
// _strdup(str)
name = "_strdup"
or
// _wcsdup(str)
name = "_wcsdup"
or
// _mbsdup(str)
name = "_mbsdup"
)
)
hasGlobalName([
"strdup", // strdup(str)
"wcsdup", // wcsdup(str)
"_strdup", // _strdup(str)
"_wcsdup", // _wcsdup(str)
"_mbsdup" // _mbsdup(str)
])
}
override predicate hasArrayInput(int bufParam) { bufParam = 0 }

View File

@@ -93,16 +93,10 @@ abstract class AllocationExpr extends Expr {
*/
class OperatorNewAllocationFunction extends AllocationFunction {
OperatorNewAllocationFunction() {
exists(string name |
hasGlobalName(name) and
(
// operator new(bytes, ...)
name = "operator new"
or
// operator new[](bytes, ...)
name = "operator new[]"
)
)
hasGlobalName([
"operator new", // operator new(bytes, ...)
"operator new[]" // operator new[](bytes, ...)
])
}
override int getSizeArg() { result = 0 }

View File

@@ -38,16 +38,10 @@ abstract class DeallocationExpr extends Expr {
*/
class OperatorDeleteDeallocationFunction extends DeallocationFunction {
OperatorDeleteDeallocationFunction() {
exists(string name |
hasGlobalName(name) and
(
// operator delete(pointer, ...)
name = "operator delete"
or
// operator delete[](pointer, ...)
name = "operator delete[]"
)
)
hasGlobalName([
"operator delete", // operator delete(pointer, ...)
"operator delete[]" // operator delete[](pointer, ...)
])
}
override int getFreedArg() { result = 0 }

View File

@@ -42,13 +42,11 @@ abstract class BufferAccess extends Expr {
*/
class MemcpyBA extends BufferAccess {
MemcpyBA() {
this.(FunctionCall).getTarget().getName() = "memcpy" or
this.(FunctionCall).getTarget().getName() = "wmemcpy" or
this.(FunctionCall).getTarget().getName() = "memmove" or
this.(FunctionCall).getTarget().getName() = "wmemmove" or
this.(FunctionCall).getTarget().getName() = "mempcpy" or
this.(FunctionCall).getTarget().getName() = "wmempcpy" or
this.(FunctionCall).getTarget().getName() = "RtlCopyMemoryNonTemporal"
this.(FunctionCall).getTarget().getName() =
[
"memcpy", "wmemcpy", "memmove", "wmemmove", "mempcpy", "wmempcpy",
"RtlCopyMemoryNonTemporal"
]
}
override string getName() { result = this.(FunctionCall).getTarget().getName() }
@@ -157,10 +155,7 @@ class MemccpyBA extends BufferAccess {
*/
class MemcmpBA extends BufferAccess {
MemcmpBA() {
this.(FunctionCall).getTarget().getName() = "memcmp" or
this.(FunctionCall).getTarget().getName() = "wmemcmp" or
this.(FunctionCall).getTarget().getName() = "_memicmp" or
this.(FunctionCall).getTarget().getName() = "_memicmp_l"
this.(FunctionCall).getTarget().getName() = ["memcmp", "wmemcmp", "_memicmp", "_memicmp_l"]
}
override string getName() { result = this.(FunctionCall).getTarget().getName() }
@@ -188,10 +183,7 @@ class MemcmpBA extends BufferAccess {
* _swab(src, dest, num)
*/
class SwabBA extends BufferAccess {
SwabBA() {
this.(FunctionCall).getTarget().getName() = "swab" or
this.(FunctionCall).getTarget().getName() = "_swab"
}
SwabBA() { this.(FunctionCall).getTarget().getName() = ["swab", "_swab"] }
override string getName() { result = this.(FunctionCall).getTarget().getName() }
@@ -218,10 +210,7 @@ class SwabBA extends BufferAccess {
* wmemset(dest, value, num)
*/
class MemsetBA extends BufferAccess {
MemsetBA() {
this.(FunctionCall).getTarget().getName() = "memset" or
this.(FunctionCall).getTarget().getName() = "wmemset"
}
MemsetBA() { this.(FunctionCall).getTarget().getName() = ["memset", "wmemset"] }
override string getName() { result = this.(FunctionCall).getTarget().getName() }
@@ -262,10 +251,7 @@ class ZeroMemoryBA extends BufferAccess {
* wmemchr(buffer, value, num)
*/
class MemchrBA extends BufferAccess {
MemchrBA() {
this.(FunctionCall).getTarget().getName() = "memchr" or
this.(FunctionCall).getTarget().getName() = "wmemchr"
}
MemchrBA() { this.(FunctionCall).getTarget().getName() = ["memchr", "wmemchr"] }
override string getName() { result = this.(FunctionCall).getTarget().getName() }

View File

@@ -168,17 +168,14 @@ class ArrayExecFunctionCall extends FunctionCall {
* for testing purposes.
*/
predicate shellCommandPreface(string cmd, string flag) {
(cmd = "sh" or cmd = "/bin/sh" or cmd = "bash" or cmd = "/bin/bash") and
cmd = ["sh", "/bin/sh", "bash", "/bin/bash"] and
flag = "-c"
or
(
cmd = "cmd" or
cmd = "cmd.exe" or
cmd = "CMD" or
cmd = "CMD.EXE" or
cmd = "%WINDIR%\\system32\\cmd.exe" // used in Juliet tests
) and
(flag = "/c" or flag = "/C")
cmd =
[
"cmd", "cmd.exe", "CMD", "CMD.EXE", "%WINDIR%\\system32\\cmd.exe" // used in Juliet tests
] and
flag = ["/c", "/C"]
}
/**

View File

@@ -8,21 +8,17 @@ import cpp
* Gets the name of an algorithm that is known to be insecure.
*/
string getAnInsecureAlgorithmName() {
result = "DES" or
result = "RC2" or
result = "RC4" or
result = "RC5" or
result = "ARCFOUR" // a variant of RC4
result =
[
"DES", "RC2", "RC4", "RC5", "ARCFOUR" // ARCFOUR is a variant of RC4
]
}
/**
* Gets the name of a hash algorithm that is insecure if it is being used for
* encryption (but it is hard to know when that is happening).
*/
string getAnInsecureHashAlgorithmName() {
result = "SHA1" or
result = "MD5"
}
string getAnInsecureHashAlgorithmName() { result = ["SHA1", "MD5"] }
/**
* Gets the regular expression used for matching strings that look like they
@@ -45,13 +41,7 @@ string getInsecureAlgorithmRegex() {
* Gets the name of an algorithm that is known to be secure.
*/
string getASecureAlgorithmName() {
result = "RSA" or
result = "SHA256" or
result = "CCM" or
result = "GCM" or
result = "AES" or
result = "Blowfish" or
result = "ECIES"
result = ["RSA", "SHA256", "CCM", "GCM", "AES", "Blowfish", "ECIES"]
}
/**

View File

@@ -20,36 +20,13 @@ class SecurityOptions extends string {
* name is a pure function of its arguments.
*/
predicate isPureFunction(string name) {
name = "abs" or
name = "atof" or
name = "atoi" or
name = "atol" or
name = "atoll" or
name = "labs" or
name = "strcasestr" or
name = "strcat" or
name = "strchnul" or
name = "strchr" or
name = "strchrnul" or
name = "strcmp" or
name = "strcpy" or
name = "strcspn" or
name = "strdup" or
name = "strlen" or
name = "strncat" or
name = "strncmp" or
name = "strncpy" or
name = "strndup" or
name = "strnlen" or
name = "strrchr" or
name = "strspn" or
name = "strstr" or
name = "strtod" or
name = "strtof" or
name = "strtol" or
name = "strtoll" or
name = "strtoq" or
name = "strtoul"
name =
[
"abs", "atof", "atoi", "atol", "atoll", "labs", "strcasestr", "strcat", "strchnul",
"strchr", "strchrnul", "strcmp", "strcpy", "strcspn", "strdup", "strlen", "strncat",
"strncmp", "strncpy", "strndup", "strnlen", "strrchr", "strspn", "strstr", "strtod",
"strtof", "strtol", "strtoll", "strtoq", "strtoul"
]
}
/**
@@ -73,13 +50,7 @@ class SecurityOptions extends string {
functionCall.getTarget().hasGlobalOrStdName(fname) and
exists(functionCall.getArgument(arg)) and
(
fname = "fread" and arg = 0
or
fname = "fgets" and arg = 0
or
fname = "fgetws" and arg = 0
or
fname = "gets" and arg = 0
fname = ["fread", "fgets", "fgetws", "gets"] and arg = 0
or
fname = "scanf" and arg >= 1
or
@@ -89,16 +60,12 @@ class SecurityOptions extends string {
functionCall.getTarget().hasGlobalName(fname) and
exists(functionCall.getArgument(arg)) and
(
fname = "read" and arg = 1
fname = ["read", "recv", "recvmsg"] and arg = 1
or
fname = "getaddrinfo" and arg = 3
or
fname = "recv" and arg = 1
or
fname = "recvfrom" and
(arg = 1 or arg = 4 or arg = 5)
or
fname = "recvmsg" and arg = 1
)
)
}
@@ -110,8 +77,7 @@ class SecurityOptions extends string {
exists(string fname |
functionCall.getTarget().getName() = fname and
(
fname = "fgets" or
fname = "gets" or
fname = ["fgets", "gets"] or
userInputReturn(fname)
)
)
@@ -132,30 +98,12 @@ class SecurityOptions extends string {
*/
predicate isProcessOperationArgument(string function, int arg) {
// POSIX
function = "system" and arg = 0
or
function = "popen" and arg = 0
or
function = "execl" and arg = 0
or
function = "execlp" and arg = 0
or
function = "execle" and arg = 0
or
function = "execv" and arg = 0
or
function = "execvp" and arg = 0
or
function = "execvpe" and arg = 0
or
function = "dlopen" and arg = 0
function =
["system", "popen", "execl", "execlp", "execle", "execv", "execvp", "execvpe", "dlopen"] and
arg = 0
or
// Windows
function = "LoadLibrary" and arg = 0
or
function = "LoadLibraryA" and arg = 0
or
function = "LoadLibraryW" and arg = 0
function = ["LoadLibrary", "LoadLibraryA", "LoadLibraryW"] and arg = 0
}
/**

View File

@@ -1,5 +1,10 @@
///// Library routines /////
typedef unsigned long size_t;
void *malloc(size_t size);
size_t strlen(const char *s);
int scanf(const char *format, ...);
int sscanf(const char *str, const char *format, ...);
int fscanf(const char *str, const char *format, ...);
@@ -13,13 +18,23 @@ int main(int argc, char **argv)
char buf1[10];
scanf("%s", buf1);
// GOOD, length is specified
char buf2[10];
sscanf(buf2, "%9s");
// GOOD, length is specified. The length should be one less than the size of the destination buffer, since the last character is the NULL terminator.
char buf2[20];
char buf3[10];
sscanf(buf2, "%9s", buf3);
// BAD, do not use scanf without specifying a length first
char file[10];
fscanf(file, "%s", buf2);
// GOOD, with 'sscanf' the input can be checked first and enough room allocated [FALSE POSITIVE]
if (argc >= 1)
{
char *src = argv[0];
char *dest = (char *)malloc(strlen(src) + 1);
sscanf(src, "%s", dest);
}
return 0;
}

View File

@@ -1,2 +1,3 @@
| MemoryUnsafeFunctionScan.cpp:14:5:14:9 | call to scanf | Dangerous use of one of the scanf functions |
| MemoryUnsafeFunctionScan.cpp:22:5:22:10 | call to fscanf | Dangerous use of one of the scanf functions |
| MemoryUnsafeFunctionScan.cpp:19:5:19:9 | call to scanf | Dangerous use of one of the scanf functions |
| MemoryUnsafeFunctionScan.cpp:28:5:28:10 | call to fscanf | Dangerous use of one of the scanf functions |
| MemoryUnsafeFunctionScan.cpp:36:3:36:8 | call to sscanf | Dangerous use of one of the scanf functions |