Skip to content

Commit 7324d17

Browse files
authored
Merge branch 'main' into amammad-ruby-YAMLunsafeLoad
2 parents e70e3e5 + c4bfb21 commit 7324d17

File tree

628 files changed

+18109
-5298
lines changed

Some content is hidden

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

628 files changed

+18109
-5298
lines changed

.github/workflows/swift.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ on:
1616
branches:
1717
- main
1818
- rc/*
19+
- codeql-cli-*
1920
push:
2021
paths:
2122
- "swift/**"
@@ -30,6 +31,7 @@ on:
3031
branches:
3132
- main
3233
- rc/*
34+
- codeql-cli-*
3335

3436
jobs:
3537
# not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks

config/identical-files.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,8 @@
511511
"SensitiveDataHeuristics Python/JS": [
512512
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
513513
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll",
514-
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll"
514+
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
515+
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll"
515516
],
516517
"CFG": [
517518
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
@@ -598,4 +599,4 @@
598599
"python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll",
599600
"java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll"
600601
]
601-
}
602+
}

cpp/ql/lib/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## 0.7.2
2+
3+
### New Features
4+
5+
* Added an AST-based interface (`semmle.code.cpp.rangeanalysis.new.RangeAnalysis`) for the relative range analysis library.
6+
* A new predicate `BarrierGuard::getAnIndirectBarrierNode` has been added to the new dataflow library (`semmle.code.cpp.dataflow.new.DataFlow`) to mark indirect expressions as barrier nodes using the `BarrierGuard` API.
7+
8+
### Major Analysis Improvements
9+
10+
* In the intermediate representation, handling of control flow after non-returning calls has been improved. This should remove false positives in queries that use the intermedite representation or libraries based on it, including the new data flow library.
11+
12+
### Minor Analysis Improvements
13+
14+
* The `StdNamespace` class now also includes all inline namespaces that are children of `std` namespace.
15+
* The new dataflow (`semmle.code.cpp.dataflow.new.DataFlow`) and taint-tracking libraries (`semmle.code.cpp.dataflow.new.TaintTracking`) now support tracking flow through static local variables.
16+
117
## 0.7.1
218

319
No user-facing changes.

cpp/ql/lib/change-notes/2023-04-28-indirect-barrier-node.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

cpp/ql/lib/change-notes/2023-04-28-static-local-dataflow.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

cpp/ql/lib/change-notes/2023-05-02-ir-noreturn-calls.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

cpp/ql/lib/change-notes/2023-05-02-range-analysis-wrapper.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

cpp/ql/lib/change-notes/2023-05-22-inline-in-std-namespace.md

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## 0.7.2
2+
3+
### New Features
4+
5+
* Added an AST-based interface (`semmle.code.cpp.rangeanalysis.new.RangeAnalysis`) for the relative range analysis library.
6+
* A new predicate `BarrierGuard::getAnIndirectBarrierNode` has been added to the new dataflow library (`semmle.code.cpp.dataflow.new.DataFlow`) to mark indirect expressions as barrier nodes using the `BarrierGuard` API.
7+
8+
### Major Analysis Improvements
9+
10+
* In the intermediate representation, handling of control flow after non-returning calls has been improved. This should remove false positives in queries that use the intermedite representation or libraries based on it, including the new data flow library.
11+
12+
### Minor Analysis Improvements
13+
14+
* The `StdNamespace` class now also includes all inline namespaces that are children of `std` namespace.
15+
* The new dataflow (`semmle.code.cpp.dataflow.new.DataFlow`) and taint-tracking libraries (`semmle.code.cpp.dataflow.new.TaintTracking`) now support tracking flow through static local variables.

cpp/ql/lib/codeql-pack.release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
lastReleaseVersion: 0.7.1
2+
lastReleaseVersion: 0.7.2

cpp/ql/lib/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/cpp-all
2-
version: 0.7.2-dev
2+
version: 0.7.3-dev
33
groups: cpp
44
dbscheme: semmlecode.cpp.dbscheme
55
extractor: cpp

cpp/ql/lib/semmle/code/cpp/Macro.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Macro extends PreprocessorDirective, @ppd_define {
3434
* Gets the name of the macro. For example, `MAX` in
3535
* `#define MAX(x,y) (((x)>(y))?(x):(y))`.
3636
*/
37-
string getName() { result = this.getHead().splitAt("(", 0) }
37+
string getName() { result = this.getHead().regexpCapture("([^(]*+).*", 1) }
3838

3939
/** Holds if the macro has name `name`. */
4040
predicate hasName(string name) { this.getName() = name }

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,20 @@ class AllocationInstruction extends CallInstruction {
144144
AllocationInstruction() { this.getStaticCallTarget() instanceof Cpp::AllocationFunction }
145145
}
146146

147+
private predicate isIndirectionType(Type t) { t instanceof Indirection }
148+
149+
private predicate hasUnspecifiedBaseType(Indirection t, Type base) {
150+
base = t.getBaseType().getUnspecifiedType()
151+
}
152+
153+
/**
154+
* Holds if `t2` is the same type as `t1`, but after stripping away `result` number
155+
* of indirections.
156+
* Furthermore, specifies in `t2` been deeply stripped and typedefs has been resolved.
157+
*/
158+
private int getNumberOfIndirectionsImpl(Type t1, Type t2) =
159+
shortestDistances(isIndirectionType/1, hasUnspecifiedBaseType/2)(t1, t2, result)
160+
147161
/**
148162
* An abstract class for handling indirections.
149163
*
@@ -162,7 +176,10 @@ abstract class Indirection extends Type {
162176
* For example, the number of indirections of a variable `p` of type
163177
* `int**` is `3` (i.e., `p`, `*p` and `**p`).
164178
*/
165-
abstract int getNumberOfIndirections();
179+
final int getNumberOfIndirections() {
180+
result =
181+
getNumberOfIndirectionsImpl(this.getType(), any(Type end | not end instanceof Indirection))
182+
}
166183

167184
/**
168185
* Holds if `deref` is an instruction that behaves as a `LoadInstruction`
@@ -200,19 +217,11 @@ private class PointerOrArrayOrReferenceTypeIndirection extends Indirection insta
200217
PointerOrArrayOrReferenceTypeIndirection() {
201218
baseType = PointerOrArrayOrReferenceType.super.getBaseType()
202219
}
203-
204-
override int getNumberOfIndirections() {
205-
result = 1 + countIndirections(this.getBaseType().getUnspecifiedType())
206-
}
207220
}
208221

209222
private class PointerWrapperTypeIndirection extends Indirection instanceof PointerWrapper {
210223
PointerWrapperTypeIndirection() { baseType = PointerWrapper.super.getBaseType() }
211224

212-
override int getNumberOfIndirections() {
213-
result = 1 + countIndirections(this.getBaseType().getUnspecifiedType())
214-
}
215-
216225
override predicate isAdditionalDereference(Instruction deref, Operand address) {
217226
exists(CallInstruction call |
218227
operandForFullyConvertedCall(getAUse(deref), call) and
@@ -233,10 +242,6 @@ private module IteratorIndirections {
233242
baseType = super.getValueType()
234243
}
235244

236-
override int getNumberOfIndirections() {
237-
result = 1 + countIndirections(this.getBaseType().getUnspecifiedType())
238-
}
239-
240245
override predicate isAdditionalDereference(Instruction deref, Operand address) {
241246
exists(CallInstruction call |
242247
operandForFullyConvertedCall(getAUse(deref), call) and

cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -255,28 +255,14 @@ private module Cached {
255255
cached
256256
newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) }
257257

258-
/** Gets the index of `i` in its `IRBlock`. */
259-
private int getMemberIndex(Instruction i) {
260-
startsBasicBlock(i) and
261-
result = 0
262-
or
263-
exists(Instruction iPrev |
264-
adjacentInBlock(iPrev, i) and
265-
result = getMemberIndex(iPrev) + 1
266-
)
267-
}
268-
269-
private module BlockAdjacency = QlBuiltins::EquivalenceRelation<Instruction, adjacentInBlock/2>;
258+
/** Holds if `i` is the `index`th instruction the block starting with `first`. */
259+
private Instruction getInstructionFromFirst(Instruction first, int index) =
260+
shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index)
270261

271262
/** Holds if `i` is the `index`th instruction in `block`. */
272263
cached
273264
Instruction getInstruction(TIRBlock block, int index) {
274-
exists(Instruction first | block = MkIRBlock(first) |
275-
first = result and index = 0
276-
or
277-
index = getMemberIndex(result) and
278-
BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result)
279-
)
265+
result = getInstructionFromFirst(getFirstInstruction(block), index)
280266
}
281267

282268
cached

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -255,28 +255,14 @@ private module Cached {
255255
cached
256256
newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) }
257257

258-
/** Gets the index of `i` in its `IRBlock`. */
259-
private int getMemberIndex(Instruction i) {
260-
startsBasicBlock(i) and
261-
result = 0
262-
or
263-
exists(Instruction iPrev |
264-
adjacentInBlock(iPrev, i) and
265-
result = getMemberIndex(iPrev) + 1
266-
)
267-
}
268-
269-
private module BlockAdjacency = QlBuiltins::EquivalenceRelation<Instruction, adjacentInBlock/2>;
258+
/** Holds if `i` is the `index`th instruction the block starting with `first`. */
259+
private Instruction getInstructionFromFirst(Instruction first, int index) =
260+
shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index)
270261

271262
/** Holds if `i` is the `index`th instruction in `block`. */
272263
cached
273264
Instruction getInstruction(TIRBlock block, int index) {
274-
exists(Instruction first | block = MkIRBlock(first) |
275-
first = result and index = 0
276-
or
277-
index = getMemberIndex(result) and
278-
BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result)
279-
)
265+
result = getInstructionFromFirst(getFirstInstruction(block), index)
280266
}
281267

282268
cached

cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -255,28 +255,14 @@ private module Cached {
255255
cached
256256
newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) }
257257

258-
/** Gets the index of `i` in its `IRBlock`. */
259-
private int getMemberIndex(Instruction i) {
260-
startsBasicBlock(i) and
261-
result = 0
262-
or
263-
exists(Instruction iPrev |
264-
adjacentInBlock(iPrev, i) and
265-
result = getMemberIndex(iPrev) + 1
266-
)
267-
}
268-
269-
private module BlockAdjacency = QlBuiltins::EquivalenceRelation<Instruction, adjacentInBlock/2>;
258+
/** Holds if `i` is the `index`th instruction the block starting with `first`. */
259+
private Instruction getInstructionFromFirst(Instruction first, int index) =
260+
shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index)
270261

271262
/** Holds if `i` is the `index`th instruction in `block`. */
272263
cached
273264
Instruction getInstruction(TIRBlock block, int index) {
274-
exists(Instruction first | block = MkIRBlock(first) |
275-
first = result and index = 0
276-
or
277-
index = getMemberIndex(result) and
278-
BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result)
279-
)
265+
result = getInstructionFromFirst(getFirstInstruction(block), index)
280266
}
281267

282268
cached

cpp/ql/src/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.6.2
2+
3+
No user-facing changes.
4+
15
## 0.6.1
26

37
### New Queries
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 0.6.2
2+
3+
No user-facing changes.

cpp/ql/src/codeql-pack.release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
lastReleaseVersion: 0.6.1
2+
lastReleaseVersion: 0.6.2
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
<overview>
7+
<p>
8+
Detects <code>if (a+b>c) a=c-b</code>, which incorrectly implements
9+
<code>a = min(a,c-b)</code> if <code>a+b</code> overflows.
10+
</p>
11+
<p>
12+
Also detects variants such as <code>if (b+a>c) a=c-b</code> (swapped
13+
terms in addition), <code>if (a+b>c) { a=c-b }</code> (assignment
14+
inside block), <code>c&lt;a+b</code> (swapped operands), and
15+
<code>&gt;=</code>, <code>&lt;</code>, <code>&lt;=</code> instead of
16+
<code>&gt;</code> (all operators).
17+
</p>
18+
<p>
19+
This integer overflow is the root cause of the buffer overflow in
20+
the SHA-3 reference implementation (CVE-2022-37454).
21+
</p>
22+
</overview>
23+
<recommendation>
24+
<p>
25+
Replace by <code>if (a>c-b) a=c-b</code>. This avoids the overflow
26+
and makes it easy to see that <code>a = min(a,c-b)</code>.
27+
</p>
28+
</recommendation>
29+
<references>
30+
<li>CVE-2022-37454: <a href="https://nvd.nist.gov/vuln/detail/CVE-2022-37454">The Keccak XKCP SHA-3 reference implementation before fdc6fef has an integer overflow and resultant buffer overflow that allows attackers to execute arbitrary code or eliminate expected cryptographic properties. This occurs in the sponge function interface.</a></li>
31+
<li>GitHub Advisory Database: <a href="https://github.com/advisories/GHSA-6w4m-2xhg-2658">CVE-2022-37454: Buffer overflow in sponge queue functions</a></li>
32+
</references>
33+
</qhelp>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* @name Integer addition may overflow inside if statement
3+
* @description Writing 'if (a+b>c) a=c-b' incorrectly implements
4+
* 'a = min(a,c-b)' if 'a+b' overflows. This integer
5+
* overflow is the root cause of the buffer overflow
6+
* in the SHA-3 reference implementation (CVE-2022-37454).
7+
* @kind problem
8+
* @problem.severity warning
9+
* @id cpp/if-statement-addition-overflow
10+
* @tags: experimental
11+
* correctness
12+
* security
13+
* external/cwe/cwe-190
14+
*/
15+
16+
import cpp
17+
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
18+
import semmle.code.cpp.valuenumbering.HashCons
19+
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
20+
import semmle.code.cpp.controlflow.Guards
21+
22+
from
23+
GuardCondition guard, Expr expr, ExprStmt exprstmt, BasicBlock block, AssignExpr assignexpr,
24+
AddExpr addexpr, SubExpr subexpr
25+
where
26+
(guard.ensuresLt(expr, addexpr, 0, block, _) or guard.ensuresLt(addexpr, expr, 0, block, _)) and
27+
addexpr.getUnspecifiedType() instanceof IntegralType and
28+
exprMightOverflowPositively(addexpr) and
29+
block.getANode() = exprstmt and
30+
exprstmt.getExpr() = assignexpr and
31+
assignexpr.getRValue() = subexpr and
32+
(
33+
hashCons(addexpr.getLeftOperand()) = hashCons(assignexpr.getLValue()) and
34+
globalValueNumber(addexpr.getRightOperand()) = globalValueNumber(subexpr.getRightOperand())
35+
or
36+
hashCons(addexpr.getRightOperand()) = hashCons(assignexpr.getLValue()) and
37+
globalValueNumber(addexpr.getLeftOperand()) = globalValueNumber(subexpr.getRightOperand())
38+
) and
39+
globalValueNumber(expr) = globalValueNumber(subexpr.getLeftOperand())
40+
select guard,
41+
"\"if (a+b>c) a=c-b\" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as \"if (a>c-b) a=c-b\" which avoids the overflow.",
42+
addexpr, "addition"

cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,17 @@ predicate isInvalidPointerDerefSink2(DataFlow::Node sink, Instruction i, string
7878
)
7979
}
8080

81+
pragma[nomagic]
82+
predicate arrayTypeHasSizes(ArrayType arr, int baseTypeSize, int arraySize) {
83+
arr.getBaseType().getSize() = baseTypeSize and
84+
arr.getArraySize() = arraySize
85+
}
86+
8187
predicate pointerArithOverflow0(
8288
PointerArithmeticInstruction pai, Field f, int size, int bound, int delta
8389
) {
84-
pai.getElementSize() = f.getUnspecifiedType().(ArrayType).getBaseType().getSize() and
85-
f.getUnspecifiedType().(ArrayType).getArraySize() = size and
90+
not f.getNamespace() instanceof StdNamespace and
91+
arrayTypeHasSizes(f.getUnspecifiedType(), pai.getElementSize(), size) and
8692
semBounded(getSemanticExpr(pai.getRight()), any(SemZeroBound b), bound, true, _) and
8793
delta = bound - size and
8894
delta >= 0 and

0 commit comments

Comments
 (0)