C++: Use [,] more in general.

This commit is contained in:
Geoffrey White
2020-12-03 18:50:43 +00:00
parent 2a4fba0ff9
commit 13d9d5dc45
20 changed files with 163 additions and 520 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
@@ -291,7 +161,8 @@ predicate arrayInitializerChild(AggregateLiteral parent, Expr e) {
// i.e. not a constant folded expression
predicate literallyLiteral(Literal lit) {
lit.getValueText()
lit
.getValueText()
.regexpMatch(".*\".*|\\s*+[-+]?+\\s*+(0[xob][0-9a-fA-F]|[0-9])[0-9a-fA-F,._]*+([eE][-+]?+[0-9,._]*+)?+\\s*+[a-zA-Z]*+\\s*+")
}

View File

@@ -59,14 +59,10 @@ 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

@@ -189,7 +189,8 @@ class InitializationFunction extends Function {
// Field wise assignment to the parameter
any(Assignment e).getLValue() = getAFieldAccess(this.getParameter(i)) or
i =
this.(MemberFunction)
this
.(MemberFunction)
.getAnOverridingFunction+()
.(InitializationFunction)
.initializedParameter() or
@@ -326,52 +327,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"
]
)
}
}
@@ -474,9 +458,12 @@ class ConditionalInitializationCall extends FunctionCall {
fa.getASuccessor+() = result
) and
result =
this.getArgument(getTarget(this)
.(ConditionalInitializationFunction)
.conditionallyInitializedParameter(_)).(AddressOfExpr).getOperand()
this
.getArgument(getTarget(this)
.(ConditionalInitializationFunction)
.conditionallyInitializedParameter(_))
.(AddressOfExpr)
.getOperand()
}
Variable getStatusVariable() {

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

@@ -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,17 @@ 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) {
@@ -652,7 +640,8 @@ module TaintedWithPath {
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.inner()
this
.inner()
.getLocation()
.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}

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
}
/**