Skip to content

Commit dde9a7c

Browse files
committed
Merge branch 'main' into ts53-ts
2 parents 01e7d57 + 75f8605 commit dde9a7c

File tree

2,268 files changed

+95427
-31433
lines changed

Some content is hidden

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

2,268 files changed

+95427
-31433
lines changed

cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ IEnumerable<string> IBuildActions.EnumerateDirectories(string dir)
145145

146146
bool IBuildActions.IsMacOs() => IsMacOs;
147147

148-
public bool IsArm { get; set; }
148+
public bool IsRunningOnAppleSilicon { get; set; }
149149

150-
bool IBuildActions.IsArm() => IsArm;
150+
bool IBuildActions.IsRunningOnAppleSilicon() => IsRunningOnAppleSilicon;
151151

152152
string IBuildActions.PathCombine(params string[] parts)
153153
{

cpp/ql/lib/CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## 0.12.0
2+
3+
### Breaking Changes
4+
5+
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
6+
7+
### Minor Analysis Improvements
8+
9+
* The "Returning stack-allocated memory" (`cpp/return-stack-allocated-memory`) query now also detects returning stack-allocated memory allocated by calls to `alloca`, `strdupa`, and `strndupa`.
10+
* Added models for `strlcpy` and `strlcat`.
11+
* Added models for the `sprintf` variants from the `StrSafe.h` header.
12+
* Added SQL API models for `ODBC`.
13+
* Added taint models for `realloc` and related functions.
14+
115
## 0.11.0
216

317
### Breaking Changes

cpp/ql/lib/change-notes/2023-10-30-realloc-flow.md

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

cpp/ql/lib/change-notes/2023-10-31-assign-pointer-add-sub-expr.md

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## 0.12.0
2+
3+
### Breaking Changes
4+
5+
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
6+
7+
### Minor Analysis Improvements
8+
9+
* The "Returning stack-allocated memory" (`cpp/return-stack-allocated-memory`) query now also detects returning stack-allocated memory allocated by calls to `alloca`, `strdupa`, and `strndupa`.
10+
* Added models for `strlcpy` and `strlcat`.
11+
* Added models for the `sprintf` variants from the `StrSafe.h` header.
12+
* Added SQL API models for `ODBC`.
13+
* Added taint models for `realloc` and related functions.

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.11.0
2+
lastReleaseVersion: 0.12.0

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.11.1-dev
2+
version: 0.12.1-dev
33
groups: cpp
44
dbscheme: semmlecode.cpp.dbscheme
55
extractor: cpp

cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ abstract class MustFlowConfiguration extends string {
3131
*/
3232
abstract predicate isSink(Operand sink);
3333

34+
/**
35+
* Holds if data flow through `instr` is prohibited.
36+
*/
37+
predicate isBarrier(Instruction instr) { none() }
38+
3439
/**
3540
* Holds if the additional flow step from `node1` to `node2` must be taken
3641
* into account in the analysis.
@@ -48,18 +53,21 @@ abstract class MustFlowConfiguration extends string {
4853
*/
4954
final predicate hasFlowPath(MustFlowPathNode source, MustFlowPathSink sink) {
5055
this.isSource(source.getInstruction()) and
51-
source.getASuccessor+() = sink
56+
source.getASuccessor*() = sink
5257
}
5358
}
5459

5560
/** Holds if `node` flows from a source. */
5661
pragma[nomagic]
5762
private predicate flowsFromSource(Instruction node, MustFlowConfiguration config) {
58-
config.isSource(node)
59-
or
60-
exists(Instruction mid |
61-
step(mid, node, config) and
62-
flowsFromSource(mid, pragma[only_bind_into](config))
63+
not config.isBarrier(node) and
64+
(
65+
config.isSource(node)
66+
or
67+
exists(Instruction mid |
68+
step(mid, node, config) and
69+
flowsFromSource(mid, pragma[only_bind_into](config))
70+
)
6371
)
6472
}
6573

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

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ class Node0Impl extends TIRDataFlowNode0 {
8181
/** Gets the operands corresponding to this node, if any. */
8282
Operand asOperand() { result = this.(OperandNode0).getOperand() }
8383

84+
/** Gets the location of this node. */
85+
final Location getLocation() { result = this.getLocationImpl() }
86+
87+
/** INTERNAL: Do not use. */
88+
Location getLocationImpl() {
89+
none() // overridden by subclasses
90+
}
91+
8492
/** INTERNAL: Do not use. */
8593
string toStringImpl() {
8694
none() // overridden by subclasses
@@ -131,9 +139,15 @@ abstract class InstructionNode0 extends Node0Impl {
131139
override DataFlowType getType() { result = getInstructionType(instr, _) }
132140

133141
override string toStringImpl() {
134-
// This predicate is overridden in subclasses. This default implementation
135-
// does not use `Instruction.toString` because that's expensive to compute.
136-
result = instr.getOpcode().toString()
142+
if instr.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
143+
then result = "this"
144+
else result = instr.getAst().toString()
145+
}
146+
147+
override Location getLocationImpl() {
148+
if exists(instr.getAst().getLocation())
149+
then result = instr.getAst().getLocation()
150+
else result instanceof UnknownDefaultLocation
137151
}
138152

139153
final override predicate isGLValue() { exists(getInstructionType(instr, true)) }
@@ -173,7 +187,17 @@ abstract class OperandNode0 extends Node0Impl {
173187

174188
override DataFlowType getType() { result = getOperandType(op, _) }
175189

176-
override string toStringImpl() { result = op.toString() }
190+
override string toStringImpl() {
191+
if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
192+
then result = "this"
193+
else result = op.getDef().getAst().toString()
194+
}
195+
196+
override Location getLocationImpl() {
197+
if exists(op.getDef().getAst().getLocation())
198+
then result = op.getDef().getAst().getLocation()
199+
else result instanceof UnknownDefaultLocation
200+
}
177201

178202
final override predicate isGLValue() { exists(getOperandType(op, true)) }
179203
}
@@ -621,6 +645,24 @@ class GlobalLikeVariable extends Variable {
621645
}
622646
}
623647

648+
/**
649+
* Returns the smallest indirection for the type `t`.
650+
*
651+
* For most types this is `1`, but for `ArrayType`s (which are allocated on
652+
* the stack) this is `0`
653+
*/
654+
int getMinIndirectionsForType(Type t) {
655+
if t.getUnspecifiedType() instanceof Cpp::ArrayType then result = 0 else result = 1
656+
}
657+
658+
private int getMinIndirectionForGlobalUse(Ssa::GlobalUse use) {
659+
result = getMinIndirectionsForType(use.getUnspecifiedType())
660+
}
661+
662+
private int getMinIndirectionForGlobalDef(Ssa::GlobalDef def) {
663+
result = getMinIndirectionsForType(def.getUnspecifiedType())
664+
}
665+
624666
/**
625667
* Holds if data can flow from `node1` to `node2` in a way that loses the
626668
* calling context. For example, this would happen with flow through a
@@ -632,20 +674,20 @@ predicate jumpStep(Node n1, Node n2) {
632674
v = globalUse.getVariable() and
633675
n1.(FinalGlobalValue).getGlobalUse() = globalUse
634676
|
635-
globalUse.getIndirectionIndex() = 1 and
677+
globalUse.getIndirection() = getMinIndirectionForGlobalUse(globalUse) and
636678
v = n2.asVariable()
637679
or
638-
v = n2.asIndirectVariable(globalUse.getIndirectionIndex())
680+
v = n2.asIndirectVariable(globalUse.getIndirection())
639681
)
640682
or
641683
exists(Ssa::GlobalDef globalDef |
642684
v = globalDef.getVariable() and
643685
n2.(InitialGlobalValue).getGlobalDef() = globalDef
644686
|
645-
globalDef.getIndirectionIndex() = 1 and
687+
globalDef.getIndirection() = getMinIndirectionForGlobalDef(globalDef) and
646688
v = n1.asVariable()
647689
or
648-
v = n1.asIndirectVariable(globalDef.getIndirectionIndex())
690+
v = n1.asIndirectVariable(globalDef.getIndirection())
649691
)
650692
)
651693
}

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

Lines changed: 82 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ cached
3434
private newtype TIRDataFlowNode =
3535
TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or
3636
TVariableNode(Variable var, int indirectionIndex) {
37-
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
37+
indirectionIndex =
38+
[getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
3839
} or
3940
TPostFieldUpdateNode(FieldAddress operand, int indirectionIndex) {
4041
indirectionIndex =
@@ -346,15 +347,17 @@ class Node extends TIRDataFlowNode {
346347
* Gets the variable corresponding to this node, if any. This can be used for
347348
* modeling flow in and out of global variables.
348349
*/
349-
Variable asVariable() { this = TVariableNode(result, 1) }
350+
Variable asVariable() {
351+
this = TVariableNode(result, getMinIndirectionsForType(result.getUnspecifiedType()))
352+
}
350353

351354
/**
352355
* Gets the `indirectionIndex`'th indirection of this node's underlying variable, if any.
353356
*
354357
* This can be used for modeling flow in and out of global variables.
355358
*/
356359
Variable asIndirectVariable(int indirectionIndex) {
357-
indirectionIndex > 1 and
360+
indirectionIndex > getMinIndirectionsForType(result.getUnspecifiedType()) and
358361
this = TVariableNode(result, indirectionIndex)
359362
}
360363

@@ -432,6 +435,10 @@ private class Node0 extends Node, TNode0 {
432435

433436
override Declaration getFunction() { result = node.getFunction() }
434437

438+
override Location getLocationImpl() { result = node.getLocation() }
439+
440+
override string toStringImpl() { result = node.toString() }
441+
435442
override DataFlowType getType() { result = node.getType() }
436443

437444
override predicate isGLValue() { node.isGLValue() }
@@ -448,18 +455,6 @@ class InstructionNode extends Node0 {
448455

449456
/** Gets the instruction corresponding to this node. */
450457
Instruction getInstruction() { result = instr }
451-
452-
override Location getLocationImpl() {
453-
if exists(instr.getAst().getLocation())
454-
then result = instr.getAst().getLocation()
455-
else result instanceof UnknownDefaultLocation
456-
}
457-
458-
override string toStringImpl() {
459-
if instr.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
460-
then result = "this"
461-
else result = instr.getAst().toString()
462-
}
463458
}
464459

465460
/**
@@ -473,18 +468,6 @@ class OperandNode extends Node, Node0 {
473468

474469
/** Gets the operand corresponding to this node. */
475470
Operand getOperand() { result = op }
476-
477-
override Location getLocationImpl() {
478-
if exists(op.getDef().getAst().getLocation())
479-
then result = op.getDef().getAst().getLocation()
480-
else result instanceof UnknownDefaultLocation
481-
}
482-
483-
override string toStringImpl() {
484-
if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
485-
then result = "this"
486-
else result = op.getDef().getAst().toString()
487-
}
488471
}
489472

490473
/**
@@ -1293,31 +1276,90 @@ abstract private class IndirectExprNodeBase extends Node {
12931276
}
12941277
}
12951278

1296-
private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
1297-
{
1298-
IndirectOperandIndirectExprNode() {
1279+
/** A signature for converting an indirect node to an expression. */
1280+
private signature module IndirectNodeToIndirectExprSig {
1281+
/** The indirect node class to be converted to an expression */
1282+
class IndirectNode;
1283+
1284+
/**
1285+
* Holds if the indirect expression at indirection index `indirectionIndex`
1286+
* of `node` is `e`. The integer `n` specifies how many conversions has been
1287+
* applied to `node`.
1288+
*/
1289+
predicate indirectNodeHasIndirectExpr(IndirectNode node, Expr e, int n, int indirectionIndex);
1290+
}
1291+
1292+
/**
1293+
* A module that implements the logic for deciding whether an indirect node
1294+
* should be an `IndirectExprNode`.
1295+
*/
1296+
private module IndirectNodeToIndirectExpr<IndirectNodeToIndirectExprSig Sig> {
1297+
import Sig
1298+
1299+
/**
1300+
* This predicate shifts the indirection index by one when `conv` is a
1301+
* `ReferenceDereferenceExpr`.
1302+
*
1303+
* This is necessary because `ReferenceDereferenceExpr` is a conversion
1304+
* in the AST, but appears as a `LoadInstruction` in the IR.
1305+
*/
1306+
bindingset[e, indirectionIndex]
1307+
private predicate adjustForReference(
1308+
Expr e, int indirectionIndex, Expr conv, int adjustedIndirectionIndex
1309+
) {
1310+
conv.(ReferenceDereferenceExpr).getExpr() = e and
1311+
adjustedIndirectionIndex = indirectionIndex - 1
1312+
or
1313+
not conv instanceof ReferenceDereferenceExpr and
1314+
conv = e and
1315+
adjustedIndirectionIndex = indirectionIndex
1316+
}
1317+
1318+
/** Holds if `node` should be an `IndirectExprNode`. */
1319+
predicate charpred(IndirectNode node) {
12991320
exists(Expr e, int n, int indirectionIndex |
1300-
indirectExprNodeShouldBeIndirectOperand(this, e, n, indirectionIndex) and
1301-
not indirectExprNodeShouldBeIndirectOperand(_, e, n + 1, indirectionIndex)
1321+
indirectNodeHasIndirectExpr(node, e, n, indirectionIndex) and
1322+
not exists(Expr conv, int adjustedIndirectionIndex |
1323+
adjustForReference(e, indirectionIndex, conv, adjustedIndirectionIndex) and
1324+
indirectNodeHasIndirectExpr(_, conv, n + 1, adjustedIndirectionIndex)
1325+
)
13021326
)
13031327
}
1328+
}
1329+
1330+
private module IndirectOperandIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
1331+
class IndirectNode = IndirectOperand;
1332+
1333+
predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectOperand/4;
1334+
}
1335+
1336+
module IndirectOperandToIndirectExpr =
1337+
IndirectNodeToIndirectExpr<IndirectOperandIndirectExprNodeImpl>;
1338+
1339+
private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
1340+
{
1341+
IndirectOperandIndirectExprNode() { IndirectOperandToIndirectExpr::charpred(this) }
13041342

13051343
final override Expr getConvertedExpr(int n, int index) {
1306-
indirectExprNodeShouldBeIndirectOperand(this, result, n, index)
1344+
IndirectOperandToIndirectExpr::indirectNodeHasIndirectExpr(this, result, n, index)
13071345
}
13081346
}
13091347

1348+
private module IndirectInstructionIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
1349+
class IndirectNode = IndirectInstruction;
1350+
1351+
predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectInstruction/4;
1352+
}
1353+
1354+
module IndirectInstructionToIndirectExpr =
1355+
IndirectNodeToIndirectExpr<IndirectInstructionIndirectExprNodeImpl>;
1356+
13101357
private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase instanceof IndirectInstruction
13111358
{
1312-
IndirectInstructionIndirectExprNode() {
1313-
exists(Expr e, int n, int indirectionIndex |
1314-
indirectExprNodeShouldBeIndirectInstruction(this, e, n, indirectionIndex) and
1315-
not indirectExprNodeShouldBeIndirectInstruction(_, e, n + 1, indirectionIndex)
1316-
)
1317-
}
1359+
IndirectInstructionIndirectExprNode() { IndirectInstructionToIndirectExpr::charpred(this) }
13181360

13191361
final override Expr getConvertedExpr(int n, int index) {
1320-
indirectExprNodeShouldBeIndirectInstruction(this, result, n, index)
1362+
IndirectInstructionToIndirectExpr::indirectNodeHasIndirectExpr(this, result, n, index)
13211363
}
13221364
}
13231365

0 commit comments

Comments
 (0)