Skip to content

Commit 04a48e9

Browse files
committed
Merge remote-tracking branch 'upstream/master' into SimpleRangeAnalysis-use-after-cast
2 parents 36ba56c + 76caad0 commit 04a48e9

File tree

87 files changed

+1755
-806
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+1755
-806
lines changed

change-notes/1.21/analysis-cpp.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
| **Query** | **Expected impact** | **Change** |
1313
|----------------------------|------------------------|------------------------------------------------------------------|
1414
| Mismatching new/free or malloc/delete (`cpp/new-free-mismatch`) | Fewer false positive results | Fixed an issue where functions were being identified as allocation functions inappropriately. Also affects `cpp/new-array-delete-mismatch` and `cpp/new-delete-array-mismatch`. |
15+
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | More correct results | This query has been reworked so that it can find a wider variety of results. |
16+
| Memory may not be freed (`cpp/memory-may-not-be-freed`) | More correct results | Support added for more Microsoft-specific allocation functions, including `LocalAlloc`, `GlobalAlloc`, `HeapAlloc` and `CoTaskMemAlloc`. |
17+
| Memory is never freed (`cpp/memory-never-freed`) | More correct results | Support added for more Microsoft-specific allocation functions, including `LocalAlloc`, `GlobalAlloc`, `HeapAlloc` and `CoTaskMemAlloc`. |
1518
| Resource not released in destructor (`cpp/resource-not-released-in-destructor`) | Fewer false positive results | Resource allocation and deallocation functions are now determined more accurately. |
19+
| Comparison result is always the same | Fewer false positive results | The range analysis library is now more conservative about floating point values being possibly `NaN` |
20+
| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | More correct results and fewer false positive results | This query now more accurately identifies wide and non-wide string/character format arguments on different platforms. Platform detection has also been made more accurate for the purposes of this query. |
1621

1722
## Changes to QL libraries
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Improvements to C# analysis
2+
3+
## Changes to existing queries
4+
5+
| **Query** | **Expected impact** | **Change** |
6+
|------------------------------|------------------------|-----------------------------------|
7+
8+
9+
## Changes to code extraction
10+
11+
* Named attribute arguments are now extracted.
12+
13+
## Changes to QL libraries
14+
15+
* The class `Attribute` has two new predicates: `getConstructorArgument()` and `getNamedArgument()`. The first predicate returns arguments to the underlying constructor call and the latter returns named arguments for initializing fields and properties.
16+
17+
## Changes to autobuilder

change-notes/1.21/analysis-javascript.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
| **Query** | **Expected impact** | **Change** |
1919
|--------------------------------|------------------------------|---------------------------------------------------------------------------|
2020
| Expression has no effect | Fewer false-positive results | This rule now treats uses of `Object.defineProperty` more conservatively. |
21-
| Useless assignment to property | Fewer false-positive results | This rule now ignore reads of additional getters. |
21+
| Useless assignment to property | Fewer false-positive results | This rule now ignores reads of additional getters. |
2222
| Arbitrary file write during zip extraction ("Zip Slip") | More results | This rule now considers more libraries, including tar as well as zip. |
23+
| Client-side URL redirect | Fewer false-positive results | This rule now treats URLs as safe in more cases where the hostname cannot be tampered with. |
24+
| Server-side URL redirect | Fewer false-positive results | This rule now treats URLs as safe in more cases where the hostname cannot be tampered with. |
2325

2426
## Changes to QL libraries

cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* readability
1313
*/
1414
import cpp
15+
private import semmle.code.cpp.commons.Exclusions
1516
private import semmle.code.cpp.rangeanalysis.PointlessComparison
1617
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
1718
import UnsignedGEZero
@@ -31,6 +32,7 @@ from
3132
where
3233
not cmp.isInMacroExpansion() and
3334
not cmp.isFromTemplateInstantiation(_) and
35+
not functionContainsDisabledCode(cmp.getEnclosingFunction()) and
3436
reachablePointlessComparison(cmp, left, right, value, ss) and
3537

3638
// a comparison between an enum and zero is always valid because whether

cpp/ql/src/Likely Bugs/Likely Typos/ExprHasNoEffect.ql

Lines changed: 9 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* external/cwe/cwe-561
1212
*/
1313
import cpp
14+
private import semmle.code.cpp.commons.Exclusions
1415

1516
class PureExprInVoidContext extends ExprInVoidContext {
1617
PureExprInVoidContext() { this.isPure() }
@@ -23,71 +24,29 @@ predicate accessInInitOfForStmt(Expr e) {
2324
s.getExpr() = e)
2425
}
2526

26-
/**
27-
* Holds if the preprocessor branch `pbd` is on line `pbdStartLine` in file `file`.
28-
*/
29-
predicate pbdLocation(PreprocessorBranchDirective pbd, string file, int pbdStartLine) {
30-
pbd.getLocation().hasLocationInfo(file, pbdStartLine, _, _, _)
31-
}
32-
33-
/**
34-
* Holds if the body of the function `f` is on lines `fBlockStartLine` to `fBlockEndLine` in file `file`.
35-
*/
36-
predicate functionLocation(Function f, string file, int fBlockStartLine, int fBlockEndLine) {
37-
f.getBlock().getLocation().hasLocationInfo(file, fBlockStartLine, _, fBlockEndLine, _)
38-
}
3927
/**
4028
* Holds if the function `f`, or a function called by it, contains
4129
* code excluded by the preprocessor.
4230
*/
43-
predicate containsDisabledCode(Function f) {
44-
// `f` contains a preprocessor branch that was not taken
45-
exists(PreprocessorBranchDirective pbd, string file, int pbdStartLine, int fBlockStartLine, int fBlockEndLine |
46-
functionLocation(f, file, fBlockStartLine, fBlockEndLine) and
47-
pbdLocation(pbd, file, pbdStartLine) and
48-
pbdStartLine <= fBlockEndLine and
49-
pbdStartLine >= fBlockStartLine and
50-
(
51-
pbd.(PreprocessorBranch).wasNotTaken() or
52-
53-
// an else either was not taken, or it's corresponding branch
54-
// was not taken.
55-
pbd instanceof PreprocessorElse
56-
)
57-
) or
58-
31+
predicate functionContainsDisabledCodeRecursive(Function f) {
32+
functionContainsDisabledCode(f) or
5933
// recurse into function calls
6034
exists(FunctionCall fc |
6135
fc.getEnclosingFunction() = f and
62-
containsDisabledCode(fc.getTarget())
36+
functionContainsDisabledCodeRecursive(fc.getTarget())
6337
)
6438
}
6539

66-
6740
/**
6841
* Holds if the function `f`, or a function called by it, is inside a
6942
* preprocessor branch that may have code in another arm
7043
*/
71-
predicate definedInIfDef(Function f) {
72-
exists(PreprocessorBranchDirective pbd, string file, int pbdStartLine, int pbdEndLine, int fBlockStartLine, int fBlockEndLine |
73-
functionLocation(f, file, fBlockStartLine, fBlockEndLine) and
74-
pbdLocation(pbd, file, pbdStartLine) and
75-
pbdLocation(pbd.getNext(), file, pbdEndLine) and
76-
pbdStartLine <= fBlockStartLine and
77-
pbdEndLine >= fBlockEndLine and
78-
// pbd is a preprocessor branch where multiple branches exist
79-
(
80-
pbd.getNext() instanceof PreprocessorElse or
81-
pbd instanceof PreprocessorElse or
82-
pbd.getNext() instanceof PreprocessorElif or
83-
pbd instanceof PreprocessorElif
84-
)
85-
) or
86-
44+
predicate functionDefinedInIfDefRecursive(Function f) {
45+
functionDefinedInIfDef(f) or
8746
// recurse into function calls
8847
exists(FunctionCall fc |
8948
fc.getEnclosingFunction() = f and
90-
definedInIfDef(fc.getTarget())
49+
functionDefinedInIfDefRecursive(fc.getTarget())
9150
)
9251
}
9352

@@ -121,8 +80,8 @@ where // EQExprs are covered by CompareWhereAssignMeant.ql
12180
not parent instanceof PureExprInVoidContext and
12281
not peivc.getEnclosingFunction().isCompilerGenerated() and
12382
not peivc.getType() instanceof UnknownType and
124-
not containsDisabledCode(peivc.(FunctionCall).getTarget()) and
125-
not definedInIfDef(peivc.(FunctionCall).getTarget()) and
83+
not functionContainsDisabledCodeRecursive(peivc.(FunctionCall).getTarget()) and
84+
not functionDefinedInIfDefRecursive(peivc.(FunctionCall).getTarget()) and
12685
if peivc instanceof FunctionCall then
12786
exists(Function target |
12887
target = peivc.(FunctionCall).getTarget() and

cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,20 @@
1414
import cpp
1515
import semmle.code.cpp.security.TaintTracking
1616

17-
from Expr source, Expr tainted, BinaryArithmeticOperation oper,
18-
SizeofOperator sizeof, string taintCause
19-
where tainted(source, tainted)
20-
and oper.getAnOperand() = tainted
21-
and oper.getOperator() = "*"
22-
and oper.getAnOperand() = sizeof
23-
and oper != tainted
24-
and sizeof.getValue().toInt() > 1
25-
and isUserInput(source, taintCause)
26-
select
27-
oper, "This allocation size is derived from $@ and might overflow",
28-
source, "user input (" + taintCause + ")"
17+
predicate taintedAllocSize(Expr e, Expr source, string taintCause) {
18+
(
19+
isAllocationExpr(e) or
20+
any(MulExpr me | me.getAChild() instanceof SizeofOperator) = e
21+
) and
22+
exists(Expr tainted |
23+
tainted = e.getAChild() and
24+
tainted.getType().getUnspecifiedType() instanceof IntegralType and
25+
isUserInput(source, taintCause) and
26+
tainted(source, tainted)
27+
)
28+
}
29+
30+
from Expr e, Expr source, string taintCause
31+
where taintedAllocSize(e, source, taintCause)
32+
select e, "This allocation size is derived from $@ and might overflow", source,
33+
"user input (" + taintCause + ")"

cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.qhelp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ some are after the final <code>#endif</code>. All three of these things must be
6868
<li>
6969
<a href="http://www.cplusplus.com/forum/articles/10627/">Headers and Includes: Why and How</a>
7070
</li>
71+
<li>
72+
<a href="https://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html">The Multiple-Include Optimization</a>
73+
</li>
7174

7275

7376
</references>

cpp/ql/src/semmle/code/cpp/File.qll

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,13 @@ class File extends Container, @file {
302302
predicate compiledAsMicrosoft() {
303303
exists(Compilation c |
304304
c.getAFileCompiled() = this and
305-
c.getAnArgument() = "--microsoft"
305+
(
306+
c.getAnArgument() = "--microsoft" or
307+
c.getAnArgument().toLowerCase().replaceAll("\\", "/").matches("%/cl.exe")
308+
)
309+
) or exists(File parent |
310+
parent.compiledAsMicrosoft() and
311+
parent.getAnIncludedFile() = this
306312
)
307313
}
308314

cpp/ql/src/semmle/code/cpp/commons/Alloc.qll

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,16 @@ predicate allocationFunction(Function f)
3939
name = "MmAllocateNodePagesForMdlEx" or
4040
name = "MmMapLockedPagesWithReservedMapping" or
4141
name = "MmMapLockedPages" or
42-
name = "MmMapLockedPagesSpecifyCache"
42+
name = "MmMapLockedPagesSpecifyCache" or
43+
name = "LocalAlloc" or
44+
name = "LocalReAlloc" or
45+
name = "GlobalAlloc" or
46+
name = "GlobalReAlloc" or
47+
name = "HeapAlloc" or
48+
name = "HeapReAlloc" or
49+
name = "VirtualAlloc" or
50+
name = "CoTaskMemAlloc" or
51+
name = "CoTaskMemRealloc"
4352
)
4453
)
4554
}
@@ -81,7 +90,17 @@ predicate freeFunction(Function f, int argNum)
8190
(name = "MmFreeMappingAddress" and argNum = 0) or
8291
(name = "MmFreePagesFromMdl" and argNum = 0) or
8392
(name = "MmUnmapReservedMapping" and argNum = 0) or
84-
(name = "MmUnmapLockedPages" and argNum = 0)
93+
(name = "MmUnmapLockedPages" and argNum = 0) or
94+
(name = "LocalFree" and argNum = 0) or
95+
(name = "GlobalFree" and argNum = 0) or
96+
(name = "HeapFree" and argNum = 2) or
97+
(name = "VirtualFree" and argNum = 0) or
98+
(name = "CoTaskMemFree" and argNum = 0) or
99+
(name = "SysFreeString" and argNum = 0) or
100+
(name = "LocalReAlloc" and argNum = 0) or
101+
(name = "GlobalReAlloc" and argNum = 0) or
102+
(name = "HeapReAlloc" and argNum = 2) or
103+
(name = "CoTaskMemRealloc" and argNum = 0)
85104
)
86105
)
87106
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* Common predicates used to exclude results from a query based on heuristics.
3+
*/
4+
5+
import cpp
6+
7+
/**
8+
* Holds if the preprocessor branch `pbd` is on line `pbdStartLine` in file `file`.
9+
*/
10+
private predicate pbdLocation(PreprocessorBranchDirective pbd, string file, int pbdStartLine) {
11+
pbd.getLocation().hasLocationInfo(file, pbdStartLine, _, _, _)
12+
}
13+
14+
/**
15+
* Holds if the body of the function `f` is on lines `fBlockStartLine` to `fBlockEndLine` in file `file`.
16+
*/
17+
private predicate functionLocation(Function f, string file, int fBlockStartLine, int fBlockEndLine) {
18+
f.getBlock().getLocation().hasLocationInfo(file, fBlockStartLine, _, fBlockEndLine, _)
19+
}
20+
21+
/**
22+
* Holds if the function `f` is inside a preprocessor branch that may have code in another arm.
23+
*/
24+
predicate functionDefinedInIfDef(Function f) {
25+
exists(PreprocessorBranchDirective pbd, string file, int pbdStartLine, int pbdEndLine, int fBlockStartLine,
26+
int fBlockEndLine |
27+
functionLocation(f, file, fBlockStartLine, fBlockEndLine) and
28+
pbdLocation(pbd, file, pbdStartLine) and
29+
pbdLocation(pbd.getNext(), file, pbdEndLine) and
30+
pbdStartLine <= fBlockStartLine and
31+
pbdEndLine >= fBlockEndLine and
32+
// pbd is a preprocessor branch where multiple branches exist
33+
(
34+
pbd.getNext() instanceof PreprocessorElse or
35+
pbd instanceof PreprocessorElse or
36+
pbd.getNext() instanceof PreprocessorElif or
37+
pbd instanceof PreprocessorElif
38+
)
39+
)
40+
}
41+
42+
/**
43+
* Holds if the function `f` contains code excluded by the preprocessor.
44+
*/
45+
predicate functionContainsDisabledCode(Function f) {
46+
// `f` contains a preprocessor branch that was not taken
47+
exists(PreprocessorBranchDirective pbd, string file, int pbdStartLine, int fBlockStartLine, int fBlockEndLine |
48+
functionLocation(f, file, fBlockStartLine, fBlockEndLine) and
49+
pbdLocation(pbd, file, pbdStartLine) and
50+
pbdStartLine <= fBlockEndLine and
51+
pbdStartLine >= fBlockStartLine and
52+
(
53+
pbd.(PreprocessorBranch).wasNotTaken() or
54+
55+
// an else either was not taken, or it's corresponding branch
56+
// was not taken.
57+
pbd instanceof PreprocessorElse
58+
)
59+
)
60+
}

0 commit comments

Comments
 (0)