Skip to content

Commit 406ac15

Browse files
authored
Merge branch 'main' into post-release-prep/codeql-cli-2.20.0
2 parents dbe8f98 + 7050100 commit 406ac15

File tree

174 files changed

+3285
-3135
lines changed

Some content is hidden

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

174 files changed

+3285
-3135
lines changed

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

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2275,6 +2275,12 @@ private predicate guardControlsPhiInput(
22752275
*/
22762276
signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch);
22772277

2278+
bindingset[g, n]
2279+
pragma[inline_late]
2280+
private predicate controls(IRGuardCondition g, Node n, boolean edge) {
2281+
g.controls(n.getBasicBlock(), edge)
2282+
}
2283+
22782284
/**
22792285
* Provides a set of barrier nodes for a guard that validates an expression.
22802286
*
@@ -2318,15 +2324,17 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
23182324
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
23192325
e = value.getAnInstruction().getConvertedResultExpression() and
23202326
result.asConvertedExpr() = e and
2321-
guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and
2322-
g.controls(result.getBasicBlock(), edge)
2327+
guardChecks(g,
2328+
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and
2329+
controls(g, result, edge)
23232330
)
23242331
or
23252332
exists(
23262333
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
23272334
|
23282335
guardChecks(g, def.getARead().asOperand().getDef().getConvertedResultExpression(), branch) and
2329-
guardControlsPhiInput(g, branch, def, input, phi) and
2336+
guardControlsPhiInput(g, branch, def, pragma[only_bind_into](input),
2337+
pragma[only_bind_into](phi)) and
23302338
result = TSsaPhiInputNode(phi, input)
23312339
)
23322340
}
@@ -2404,8 +2412,9 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
24042412
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
24052413
e = value.getAnInstruction().getConvertedResultExpression() and
24062414
result.asIndirectConvertedExpr(indirectionIndex) = e and
2407-
guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and
2408-
g.controls(result.getBasicBlock(), edge)
2415+
guardChecks(g,
2416+
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and
2417+
controls(g, result, edge)
24092418
)
24102419
or
24112420
exists(
@@ -2414,7 +2423,8 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
24142423
guardChecks(g,
24152424
def.getARead().asIndirectOperand(indirectionIndex).getDef().getConvertedResultExpression(),
24162425
branch) and
2417-
guardControlsPhiInput(g, branch, def, input, phi) and
2426+
guardControlsPhiInput(g, branch, def, pragma[only_bind_into](input),
2427+
pragma[only_bind_into](phi)) and
24182428
result = TSsaPhiInputNode(phi, input)
24192429
)
24202430
}
@@ -2443,17 +2453,18 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
24432453
/** Gets a node that is safely guarded by the given guard check. */
24442454
Node getABarrierNode() {
24452455
exists(IRGuardCondition g, ValueNumber value, boolean edge, Operand use |
2446-
instructionGuardChecks(g, value.getAnInstruction(), edge) and
2456+
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge) and
24472457
use = value.getAnInstruction().getAUse() and
24482458
result.asOperand() = use and
2449-
g.controls(result.getBasicBlock(), edge)
2459+
controls(g, result, edge)
24502460
)
24512461
or
24522462
exists(
24532463
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
24542464
|
24552465
instructionGuardChecks(g, def.getARead().asOperand().getDef(), branch) and
2456-
guardControlsPhiInput(g, branch, def, input, phi) and
2466+
guardControlsPhiInput(g, branch, def, pragma[only_bind_into](input),
2467+
pragma[only_bind_into](phi)) and
24572468
result = TSsaPhiInputNode(phi, input)
24582469
)
24592470
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,7 @@ class DefinitionExt extends SsaImpl::DefinitionExt {
12761276
}
12771277

12781278
/** Gets a node that represents a read of this SSA definition. */
1279+
pragma[nomagic]
12791280
Node getARead() {
12801281
exists(SourceVariable sv, IRBlock bb, int i | SsaCached::ssaDefReachesReadExt(sv, this, bb, i) |
12811282
useToNode(bb, i, sv, result)

cpp/ql/lib/semmle/code/cpp/ir/implementation/EdgeKind.qll

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ private newtype TEdgeKind =
88
TGotoEdge() or // Single successor (including fall-through)
99
TTrueEdge() or // 'true' edge of conditional branch
1010
TFalseEdge() or // 'false' edge of conditional branch
11-
TExceptionEdge() or // Thrown exception
11+
TCppExceptionEdge() or // Thrown C++ exception
12+
TSehExceptionEdge() or // Thrown SEH exception
1213
TDefaultEdge() or // 'default' label of switch
1314
TCaseEdge(string minValue, string maxValue) {
1415
// Case label of switch
@@ -20,56 +21,77 @@ private newtype TEdgeKind =
2021
* `Instruction` or `IRBlock` has at most one successor of any single
2122
* `EdgeKind`.
2223
*/
23-
abstract class EdgeKind extends TEdgeKind {
24+
abstract private class EdgeKindImpl extends TEdgeKind {
2425
/** Gets a textual representation of this edge kind. */
2526
abstract string toString();
2627
}
2728

29+
final class EdgeKind = EdgeKindImpl;
30+
2831
/**
2932
* A "goto" edge, representing the unconditional successor of an `Instruction`
3033
* or `IRBlock`.
3134
*/
32-
class GotoEdge extends EdgeKind, TGotoEdge {
35+
class GotoEdge extends EdgeKindImpl, TGotoEdge {
3336
final override string toString() { result = "Goto" }
3437
}
3538

3639
/**
3740
* A "true" edge, representing the successor of a conditional branch when the
3841
* condition is non-zero.
3942
*/
40-
class TrueEdge extends EdgeKind, TTrueEdge {
43+
class TrueEdge extends EdgeKindImpl, TTrueEdge {
4144
final override string toString() { result = "True" }
4245
}
4346

4447
/**
4548
* A "false" edge, representing the successor of a conditional branch when the
4649
* condition is zero.
4750
*/
48-
class FalseEdge extends EdgeKind, TFalseEdge {
51+
class FalseEdge extends EdgeKindImpl, TFalseEdge {
4952
final override string toString() { result = "False" }
5053
}
5154

55+
abstract private class ExceptionEdgeImpl extends EdgeKindImpl { }
56+
5257
/**
5358
* An "exception" edge, representing the successor of an instruction when that
5459
* instruction's evaluation throws an exception.
60+
*
61+
* Exception edges are expclitly sublcassed to `CppExceptionEdge` and `SehExceptionEdge`
62+
* only. Further sublcasses, if required, should be added privately here for IR efficiency.
63+
*/
64+
final class ExceptionEdge = ExceptionEdgeImpl;
65+
66+
/**
67+
* An "exception" edge, representing the successor of an instruction when that
68+
* instruction's evaluation throws a C++ exception.
69+
*/
70+
class CppExceptionEdge extends ExceptionEdgeImpl, TCppExceptionEdge {
71+
final override string toString() { result = "C++ Exception" }
72+
}
73+
74+
/**
75+
* An "exception" edge, representing the successor of an instruction when that
76+
* instruction's evaluation throws an SEH exception.
5577
*/
56-
class ExceptionEdge extends EdgeKind, TExceptionEdge {
57-
final override string toString() { result = "Exception" }
78+
class SehExceptionEdge extends ExceptionEdgeImpl, TSehExceptionEdge {
79+
final override string toString() { result = "SEH Exception" }
5880
}
5981

6082
/**
6183
* A "default" edge, representing the successor of a `Switch` instruction when
6284
* none of the case values matches the condition value.
6385
*/
64-
class DefaultEdge extends EdgeKind, TDefaultEdge {
86+
class DefaultEdge extends EdgeKindImpl, TDefaultEdge {
6587
final override string toString() { result = "Default" }
6688
}
6789

6890
/**
6991
* A "case" edge, representing the successor of a `Switch` instruction when the
7092
* the condition value matches a corresponding `case` label.
7193
*/
72-
class CaseEdge extends EdgeKind, TCaseEdge {
94+
class CaseEdge extends EdgeKindImpl, TCaseEdge {
7395
string minValue;
7496
string maxValue;
7597

@@ -121,9 +143,14 @@ module EdgeKind {
121143
FalseEdge falseEdge() { result = TFalseEdge() }
122144

123145
/**
124-
* Gets the single instance of the `ExceptionEdge` class.
146+
* Gets the single instance of the `CppExceptionEdge` class.
147+
*/
148+
CppExceptionEdge cppExceptionEdge() { result = TCppExceptionEdge() }
149+
150+
/**
151+
* Gets the single instance of the `SehExceptionEdge` class.
125152
*/
126-
ExceptionEdge exceptionEdge() { result = TExceptionEdge() }
153+
SehExceptionEdge sehExceptionEdge() { result = TSehExceptionEdge() }
127154

128155
/**
129156
* Gets the single instance of the `DefaultEdge` class.

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ abstract class TranslatedCall extends TranslatedExpr {
8888
result = this.getParent().getChildSuccessor(this, kind)
8989
or
9090
this.mayThrowException() and
91-
kind instanceof ExceptionEdge and
91+
kind instanceof CppExceptionEdge and
9292
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge edge))
9393
)
9494
}

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3039,7 +3039,7 @@ class TranslatedDestructorsAfterThrow extends TranslatedElement, TTranslatedDest
30393039
or
30403040
// And otherwise, exit this element with an exceptional edge
30413041
not exists(this.getChild(id + 1)) and
3042-
kind instanceof ExceptionEdge and
3042+
kind instanceof CppExceptionEdge and
30433043
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge edge))
30443044
)
30453045
}
@@ -3078,7 +3078,7 @@ abstract class TranslatedThrowExpr extends TranslatedNonConstantExpr {
30783078
result = this.getDestructors().getFirstInstruction(kind)
30793079
or
30803080
not exists(this.getDestructors()) and
3081-
kind instanceof ExceptionEdge and
3081+
kind instanceof CppExceptionEdge and
30823082
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge edge))
30833083
)
30843084
}

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ class TranslatedCatchByTypeHandler extends TranslatedHandler {
932932
kind instanceof GotoEdge and
933933
result = this.getParameter().getFirstInstruction(kind)
934934
or
935-
kind instanceof ExceptionEdge and
935+
kind instanceof CppExceptionEdge and
936936
if exists(this.getDestructors())
937937
then result = this.getDestructors().getFirstInstruction(any(GotoEdge edge))
938938
else result = this.getParent().(TranslatedTryStmt).getNextHandler(this, any(GotoEdge edge))

cpp/ql/src/Best Practices/GuardedFree.ql

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@ predicate blockContainsPreprocessorBranches(BasicBlock bb) {
2727
)
2828
}
2929

30-
from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb
31-
where
30+
/**
31+
* Holds if `gc` ensures that `v` is non-zero when reaching `bb`, and `bb`
32+
* contains a single statement which is `fc`.
33+
*/
34+
pragma[nomagic]
35+
private predicate interesting(GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb) {
3236
gc.ensuresEq(v.getAnAccess(), 0, bb, false) and
3337
fc.getArgument(0) = v.getAnAccess() and
3438
bb = fc.getBasicBlock() and
@@ -39,9 +43,21 @@ where
3943
// Block statement with a single nested statement: if (x) { free(x); }
4044
strictcount(bb.(BlockStmt).getAStmt()) = 1
4145
) and
42-
strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1 and
4346
not fc.isInMacroExpansion() and
4447
not blockContainsPreprocessorBranches(bb) and
4548
not (gc instanceof BinaryOperation and not gc instanceof ComparisonOperation) and
4649
not exists(CommaExpr c | c.getAChild*() = fc)
50+
}
51+
52+
/** Holds if `gc` only guards a single block. */
53+
bindingset[gc]
54+
pragma[inline_late]
55+
private predicate guardConditionGuardsUniqueBlock(GuardCondition gc) {
56+
strictcount(BasicBlock bb | gc.ensuresEq(_, 0, bb, _)) = 1
57+
}
58+
59+
from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb
60+
where
61+
interesting(gc, fc, v, bb) and
62+
guardConditionGuardsUniqueBlock(gc)
4763
select gc, "unnecessary NULL check before call to $@", fc, "free"

cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ where
4444
) and
4545
// A typical problem is that string literals are concatenated, but if one of the string
4646
// literals is an undefined macro, then this just leads to a syntax error.
47-
not exists(SyntaxError e | e.affects(fl))
47+
not exists(SyntaxError e | e.affects(fl)) and
48+
not ffc.getArgument(_) instanceof ErrorExpr
4849
select ffc,
4950
"Format for " + ffcName + " expects " + expected.toString() + " arguments but given " +
5051
given.toString()

cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ where
170170
) and
171171
not arg.isAffectedByMacro() and
172172
not arg.isFromUninstantiatedTemplate(_) and
173-
not actual.getUnspecifiedType() instanceof ErroneousType and
173+
not actual.stripType() instanceof ErroneousType and
174174
not arg.(Call).mayBeFromImplicitlyDeclaredFunction()
175175
select arg,
176176
"This format specifier for type '" + expected.getName() + "' does not match the argument type '" +

cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ from BufferWrite bw, int destSize
2525
where
2626
bw.hasExplicitLimit() and // has an explicit size limit
2727
destSize = max(getBufferSize(bw.getDest(), _)) and
28-
bw.getExplicitLimit() > destSize // but it's larger than the destination
28+
bw.getExplicitLimit() > destSize and // but it's larger than the destination
29+
not bw.getDest().getType().stripType() instanceof ErroneousType // destSize may be incorrect
2930
select bw,
3031
"This '" + bw.getBWDesc() + "' operation is limited to " + bw.getExplicitLimit() +
3132
" bytes but the destination is only " + destSize + " bytes."

0 commit comments

Comments
 (0)