mirror of
https://github.com/github/codeql.git
synced 2026-05-02 04:05:14 +02:00
C++: Use [,] more in general.
This commit is contained in:
@@ -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*+")
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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() }
|
||||
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 + "%")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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"
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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" }
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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() }
|
||||
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user