Skip to content

Commit 5f659f6

Browse files
author
Benjamin Muskalla
committed
Merge branch 'main' into fixHiddenTypesTestGenerator
2 parents 70e1724 + ee46717 commit 5f659f6

File tree

308 files changed

+10921
-1343
lines changed

Some content is hidden

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

308 files changed

+10921
-1343
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ This open source repository contains the standard CodeQL libraries and queries t
44

55
## How do I learn CodeQL and run queries?
66

7-
There is [extensive documentation](https://help.semmle.com/QL/learn-ql/) on getting started with writing CodeQL.
8-
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode.html) extension to try out your queries on any open source project that's currently being analyzed.
7+
There is [extensive documentation](https://codeql.github.com/docs/) on getting started with writing CodeQL.
8+
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://codeql.github.com/docs/codeql-for-visual-studio-code/) extension to try out your queries on any open source project that's currently being analyzed.
99

1010
## Contributing
1111

cpp/ql/lib/semmle/code/cpp/commons/NullTermination.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ predicate variableMustBeNullTerminated(VariableAccess va) {
9393
fc.getArgument(i) = va
9494
)
9595
or
96+
// String argument to a formatting function (such as `printf`)
97+
exists(int n, FormatLiteral fl |
98+
fc.(FormattingFunctionCall).getConversionArgument(n) = va and
99+
fl = fc.(FormattingFunctionCall).getFormat() and
100+
fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc
101+
not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p`
102+
not fl.hasPrecision(n) // exclude: `%.*s`
103+
)
104+
or
96105
// Call to a wrapper function that requires null termination
97106
// (not itself adding a null terminator)
98107
exists(Function wrapper, int i, Parameter p, VariableAccess use |

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,39 @@ module TaintedWithPath {
550550
)
551551
}
552552

553+
/**
554+
* Holds if there is flow from `arg` to `out` across a call that can by summarized by the flow
555+
* from `par` to `ret` within it, in the graph of data flow path explanations.
556+
*/
557+
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
558+
DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(),
559+
ret.(WrapPathNode).inner(), out.(WrapPathNode).inner())
560+
or
561+
// To avoid showing trivial-looking steps, we _replace_ the last node instead
562+
// of adding an edge out of it.
563+
exists(WrapPathNode sinkNode |
564+
DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(),
565+
ret.(WrapPathNode).inner(), sinkNode.inner()) and
566+
out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
567+
)
568+
or
569+
// Same for the first node
570+
exists(WrapPathNode sourceNode |
571+
DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(),
572+
ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) and
573+
sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner())
574+
)
575+
or
576+
// Finally, handle the case where the path goes directly from a source to a
577+
// sink, meaning that they both need to be translated.
578+
exists(WrapPathNode sinkNode, WrapPathNode sourceNode |
579+
DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(),
580+
ret.(WrapPathNode).inner(), sinkNode.inner()) and
581+
sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) and
582+
out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
583+
)
584+
}
585+
553586
/** Holds if `n` is a node in the graph of data flow path explanations. */
554587
query predicate nodes(PathNode n, string key, string val) {
555588
key = "semmle.label" and val = n.toString()

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
18561856
}
18571857

18581858
/**
1859-
* Gets the address of the allocation this instruction is initializing.
1859+
* Gets the operand that represents the address of the allocation this instruction is initializing.
18601860
*/
18611861
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
18621862

18631863
/**
1864-
* Gets the operand for the allocation this instruction is initializing.
1864+
* Gets the address for the allocation this instruction is initializing.
18651865
*/
18661866
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
18671867
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
18561856
}
18571857

18581858
/**
1859-
* Gets the address of the allocation this instruction is initializing.
1859+
* Gets the operand that represents the address of the allocation this instruction is initializing.
18601860
*/
18611861
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
18621862

18631863
/**
1864-
* Gets the operand for the allocation this instruction is initializing.
1864+
* Gets the address for the allocation this instruction is initializing.
18651865
*/
18661866
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
18671867
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
18561856
}
18571857

18581858
/**
1859-
* Gets the address of the allocation this instruction is initializing.
1859+
* Gets the operand that represents the address of the allocation this instruction is initializing.
18601860
*/
18611861
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
18621862

18631863
/**
1864-
* Gets the operand for the allocation this instruction is initializing.
1864+
* Gets the address for the allocation this instruction is initializing.
18651865
*/
18661866
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
18671867
}

cpp/ql/lib/semmle/code/cpp/rangeanalysis/NanAnalysis.qll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ predicate nanExcludingComparison(ComparisonOperation guard, boolean polarity) {
2929
*/
3030
private predicate excludesNan(RangeSsaDefinition def, VariableAccess v) {
3131
exists(VariableAccess inCond, ComparisonOperation guard, boolean branch, StackVariable lsv |
32-
def.isGuardPhi(inCond, guard, branch) and
33-
inCond.getTarget() = lsv and
32+
def.isGuardPhi(lsv, inCond, guard, branch) and
3433
v = def.getAUse(lsv) and
3534
guard.getAnOperand() = inCond and
3635
nanExcludingComparison(guard, branch)

cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,11 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
9494
predicate isPhiNode(StackVariable v) { exists(RangeSSA x | x.phi_node(v, this.(BasicBlock))) }
9595

9696
/**
97+
* DEPRECATED: Use isGuardPhi/4 instead
9798
* If this definition is a phi node corresponding to a guard,
9899
* then return the variable access and the guard.
99100
*/
100-
predicate isGuardPhi(VariableAccess va, Expr guard, boolean branch) {
101+
deprecated predicate isGuardPhi(VariableAccess va, Expr guard, boolean branch) {
101102
guard_defn(va, guard, this, branch)
102103
}
103104

@@ -142,9 +143,8 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
142143
// below excludes definitions which can only reach guard phi
143144
// nodes by going through the corresponding guard.
144145
not exists(VariableAccess access |
145-
v = access.getTarget() and
146146
pred.contains(access) and
147-
this.isGuardPhi(access, _, _)
147+
this.isGuardPhi(v, access, _, _)
148148
)
149149
)
150150
}

cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,7 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
433433
private predicate phiDependsOnDef(
434434
RangeSsaDefinition phi, StackVariable v, RangeSsaDefinition srcDef, StackVariable srcVar
435435
) {
436-
exists(VariableAccess access, Expr guard |
437-
access = v.getAnAccess() and
438-
phi.isGuardPhi(access, guard, _)
439-
|
436+
exists(VariableAccess access, Expr guard | phi.isGuardPhi(v, access, guard, _) |
440437
exprDependsOnDef(guard.(ComparisonOperation).getAnOperand(), srcDef, srcVar) or
441438
exprDependsOnDef(access, srcDef, srcVar)
442439
)
@@ -1204,8 +1201,7 @@ private float boolConversionUpperBound(Expr expr) {
12041201
*/
12051202
private float getPhiLowerBounds(StackVariable v, RangeSsaDefinition phi) {
12061203
exists(VariableAccess access, Expr guard, boolean branch, float defLB, float guardLB |
1207-
access = v.getAnAccess() and
1208-
phi.isGuardPhi(access, guard, branch) and
1204+
phi.isGuardPhi(v, access, guard, branch) and
12091205
lowerBoundFromGuard(guard, access, guardLB, branch) and
12101206
defLB = getFullyConvertedLowerBounds(access)
12111207
|
@@ -1230,8 +1226,7 @@ private float getPhiLowerBounds(StackVariable v, RangeSsaDefinition phi) {
12301226
/** See comment for `getPhiLowerBounds`, above. */
12311227
private float getPhiUpperBounds(StackVariable v, RangeSsaDefinition phi) {
12321228
exists(VariableAccess access, Expr guard, boolean branch, float defUB, float guardUB |
1233-
access = v.getAnAccess() and
1234-
phi.isGuardPhi(access, guard, branch) and
1229+
phi.isGuardPhi(v, access, guard, branch) and
12351230
upperBoundFromGuard(guard, access, guardUB, branch) and
12361231
defUB = getFullyConvertedUpperBounds(access)
12371232
|
@@ -1493,8 +1488,7 @@ private predicate isNEPhi(
14931488
exists(
14941489
ComparisonOperation cmp, boolean branch, Expr linearExpr, Expr rExpr, float p, float q, float r
14951490
|
1496-
access.getTarget() = v and
1497-
phi.isGuardPhi(access, cmp, branch) and
1491+
phi.isGuardPhi(v, access, cmp, branch) and
14981492
eqOpWithSwapAndNegate(cmp, linearExpr, rExpr, false, branch) and
14991493
v.getUnspecifiedType() instanceof IntegralOrEnumType and // Float `!=` is too imprecise
15001494
r = getValue(rExpr).toFloat() and
@@ -1503,8 +1497,7 @@ private predicate isNEPhi(
15031497
)
15041498
or
15051499
exists(Expr op, boolean branch, Expr linearExpr, float p, float q |
1506-
access.getTarget() = v and
1507-
phi.isGuardPhi(access, op, branch) and
1500+
phi.isGuardPhi(v, access, op, branch) and
15081501
eqZeroWithNegate(op, linearExpr, false, branch) and
15091502
v.getUnspecifiedType() instanceof IntegralOrEnumType and // Float `!` is too imprecise
15101503
linearAccess(linearExpr, access, p, q) and
@@ -1524,8 +1517,7 @@ private predicate isUnsupportedGuardPhi(Variable v, RangeSsaDefinition phi, Vari
15241517
or
15251518
eqZeroWithNegate(cmp, _, false, branch)
15261519
|
1527-
access.getTarget() = v and
1528-
phi.isGuardPhi(access, cmp, branch) and
1520+
phi.isGuardPhi(v, access, cmp, branch) and
15291521
not isNEPhi(v, phi, access, _)
15301522
)
15311523
}
@@ -1549,7 +1541,8 @@ private float getGuardedUpperBound(VariableAccess guardedAccess) {
15491541
// that there is one predecessor, albeit somewhat conservative.
15501542
exists(unique(BasicBlock b | b = def.(BasicBlock).getAPredecessor())) and
15511543
guardedAccess = def.getAUse(v) and
1552-
result = max(float ub | upperBoundFromGuard(guard, guardVa, ub, branch))
1544+
result = max(float ub | upperBoundFromGuard(guard, guardVa, ub, branch)) and
1545+
not convertedExprMightOverflow(guard.getAChild+())
15531546
)
15541547
}
15551548

cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBound.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,10 @@
599599
| test.c:675:7:675:7 | y | -2147483648 |
600600
| test.c:684:7:684:7 | x | -2147483648 |
601601
| test.c:689:7:689:7 | x | -2147483648 |
602+
| test.c:696:8:696:8 | x | 2147483647 |
603+
| test.c:696:12:696:12 | y | 256 |
604+
| test.c:697:9:697:9 | x | 2147483647 |
605+
| test.c:698:9:698:9 | y | 256 |
602606
| test.cpp:10:7:10:7 | b | -2147483648 |
603607
| test.cpp:11:5:11:5 | x | -2147483648 |
604608
| test.cpp:13:10:13:10 | x | -2147483648 |

0 commit comments

Comments
 (0)