Skip to content

Commit f2de449

Browse files
author
Stephan Brandauer
authored
Merge branch 'main' into kaeluka/automodel-extraction-skip-primitive-types-candidates
2 parents 737aab6 + 2c5ce32 commit f2de449

File tree

730 files changed

+42737
-1622
lines changed

Some content is hidden

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

730 files changed

+42737
-1622
lines changed

CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
/swift/ @github/codeql-swift
99
/misc/codegen/ @github/codeql-swift
1010
/java/kotlin-extractor/ @github/codeql-kotlin
11+
/java/ql/test/kotlin/ @github/codeql-kotlin
12+
/java/ql/test-kotlin2/ @github/codeql-kotlin
1113

1214
# ML-powered queries
1315
/javascript/ql/experimental/adaptivethreatmodeling/ @github/codeql-ml-powered-queries-reviewers

codeql-workspace.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
provide:
22
- "*/ql/src/qlpack.yml"
33
- "*/ql/lib/qlpack.yml"
4-
- "*/ql/test/qlpack.yml"
4+
- "*/ql/test*/qlpack.yml"
55
- "*/ql/examples/qlpack.yml"
66
- "*/ql/consistency-queries/qlpack.yml"
77
- "*/ql/automodel/src/qlpack.yml"

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,24 @@ class GlobalLikeVariable extends Variable {
645645
}
646646
}
647647

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+
648666
/**
649667
* Holds if data can flow from `node1` to `node2` in a way that loses the
650668
* calling context. For example, this would happen with flow through a
@@ -656,7 +674,7 @@ predicate jumpStep(Node n1, Node n2) {
656674
v = globalUse.getVariable() and
657675
n1.(FinalGlobalValue).getGlobalUse() = globalUse
658676
|
659-
globalUse.getIndirection() = 1 and
677+
globalUse.getIndirection() = getMinIndirectionForGlobalUse(globalUse) and
660678
v = n2.asVariable()
661679
or
662680
v = n2.asIndirectVariable(globalUse.getIndirection())
@@ -666,7 +684,7 @@ predicate jumpStep(Node n1, Node n2) {
666684
v = globalDef.getVariable() and
667685
n2.(InitialGlobalValue).getGlobalDef() = globalDef
668686
|
669-
globalDef.getIndirection() = 1 and
687+
globalDef.getIndirection() = getMinIndirectionForGlobalDef(globalDef) and
670688
v = n1.asVariable()
671689
or
672690
v = n1.asIndirectVariable(globalDef.getIndirection())

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

Lines changed: 6 additions & 3 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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ private module Cached {
872872
upper = countIndirectionsForCppType(type) and
873873
ind = ind0 + [lower .. upper] and
874874
indirectionIndex = ind - (ind0 + lower) and
875-
(if type.hasType(any(Cpp::ArrayType arrayType), true) then lower = 0 else lower = 1)
875+
lower = getMinIndirectionsForType(any(Type t | type.hasUnspecifiedType(t, _)))
876876
)
877877
}
878878

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

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,30 @@
1616

1717
import cpp
1818
import semmle.code.cpp.security.Overflow
19-
import semmle.code.cpp.security.Security
20-
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
19+
import semmle.code.cpp.dataflow.new.TaintTracking
20+
import semmle.code.cpp.ir.IR
21+
import semmle.code.cpp.controlflow.IRGuards as IRGuards
2122

2223
predicate isMaxValue(Expr mie) {
2324
exists(MacroInvocation mi |
2425
mi.getExpr() = mie and
25-
(
26-
mi.getMacroName() = "CHAR_MAX" or
27-
mi.getMacroName() = "LLONG_MAX" or
28-
mi.getMacroName() = "INT_MAX" or
29-
mi.getMacroName() = "SHRT_MAX" or
30-
mi.getMacroName() = "UINT_MAX"
31-
)
26+
mi.getMacroName() = ["CHAR_MAX", "LLONG_MAX", "INT_MAX", "SHRT_MAX", "UINT_MAX"]
3227
)
3328
}
3429

3530
predicate isMinValue(Expr mie) {
3631
exists(MacroInvocation mi |
3732
mi.getExpr() = mie and
38-
(
39-
mi.getMacroName() = "CHAR_MIN" or
40-
mi.getMacroName() = "LLONG_MIN" or
41-
mi.getMacroName() = "INT_MIN" or
42-
mi.getMacroName() = "SHRT_MIN"
43-
)
33+
mi.getMacroName() = ["CHAR_MIN", "LLONG_MIN", "INT_MIN", "SHRT_MIN"]
4434
)
4535
}
4636

47-
class SecurityOptionsArith extends SecurityOptions {
48-
override predicate isUserInput(Expr expr, string cause) {
37+
predicate isSource(DataFlow::Node source, string cause) {
38+
exists(Expr expr | expr = source.asExpr() |
4939
isMaxValue(expr) and cause = "max value"
5040
or
5141
isMinValue(expr) and cause = "min value"
52-
}
53-
}
54-
55-
predicate taintedVarAccess(Expr origin, VariableAccess va, string cause) {
56-
isUserInput(origin, cause) and
57-
tainted(origin, va)
42+
)
5843
}
5944

6045
predicate causeEffectCorrespond(string cause, string effect) {
@@ -65,16 +50,79 @@ predicate causeEffectCorrespond(string cause, string effect) {
6550
effect = "underflow"
6651
}
6752

68-
from Expr origin, Operation op, VariableAccess va, string cause, string effect
69-
where
70-
taintedVarAccess(origin, va, cause) and
71-
op.getAnOperand() = va and
72-
(
53+
predicate isSink(DataFlow::Node sink, VariableAccess va, string effect) {
54+
exists(Operation op |
55+
sink.asExpr() = va and
56+
op.getAnOperand() = va
57+
|
7358
missingGuardAgainstUnderflow(op, va) and effect = "underflow"
7459
or
7560
missingGuardAgainstOverflow(op, va) and effect = "overflow"
76-
) and
77-
causeEffectCorrespond(cause, effect)
61+
)
62+
}
63+
64+
predicate hasUpperBoundsCheck(Variable var) {
65+
exists(RelationalOperation oper, VariableAccess access |
66+
oper.getAnOperand() = access and
67+
access.getTarget() = var and
68+
// Comparing to 0 is not an upper bound check
69+
not oper.getAnOperand().getValue() = "0"
70+
)
71+
}
72+
73+
predicate constantInstruction(Instruction instr) {
74+
instr instanceof ConstantInstruction or
75+
constantInstruction(instr.(UnaryInstruction).getUnary())
76+
}
77+
78+
predicate readsVariable(LoadInstruction load, Variable var) {
79+
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
80+
}
81+
82+
predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
83+
exists(Instruction instr | instr = node.asInstruction() |
84+
readsVariable(instr, checkedVar) and
85+
any(IRGuards::IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true)
86+
)
87+
}
88+
89+
module Config implements DataFlow::ConfigSig {
90+
predicate isSource(DataFlow::Node source) { isSource(source, _) }
91+
92+
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
93+
94+
predicate isBarrier(DataFlow::Node node) {
95+
// Block flow if there's an upper bound check of the variable anywhere in the program
96+
exists(Variable checkedVar, Instruction instr | instr = node.asInstruction() |
97+
readsVariable(instr, checkedVar) and
98+
hasUpperBoundsCheck(checkedVar)
99+
)
100+
or
101+
// Block flow if the node is guarded by an equality check
102+
exists(Variable checkedVar, Operand access |
103+
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
104+
readsVariable(access.getDef(), checkedVar)
105+
)
106+
or
107+
// Block flow to any binary instruction whose operands are both non-constants.
108+
exists(BinaryInstruction iTo |
109+
iTo = node.asInstruction() and
110+
not constantInstruction(iTo.getLeft()) and
111+
not constantInstruction(iTo.getRight()) and
112+
// propagate taint from either the pointer or the offset, regardless of constantness
113+
not iTo instanceof PointerArithmeticInstruction
114+
)
115+
}
116+
}
117+
118+
module Flow = TaintTracking::Global<Config>;
119+
120+
from DataFlow::Node source, DataFlow::Node sink, VariableAccess va, string cause, string effect
121+
where
122+
Flow::flow(source, sink) and
123+
isSource(source, cause) and
124+
causeEffectCorrespond(cause, effect) and
125+
isSink(sink, va, effect)
78126
select va,
79127
"$@ flows to an operand of an arithmetic expression, potentially causing an " + effect + ".",
80-
origin, "Extreme value"
128+
source, "Extreme value"

cpp/ql/src/experimental/cryptography/inventory/new_models/AllAsymmetricAlgorithms.ql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
* @kind problem
55
* @id cpp/quantum-readiness/cbom/all-asymmetric-algorithms
66
* @problem.severity error
7-
* @precision high
87
* @tags cbom
98
* cryptography
109
*/

cpp/ql/src/experimental/cryptography/inventory/new_models/AllCryptoAlgorithms.ql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
* @kind problem
55
* @id cpp/quantum-readiness/cbom/all-cryptographic-algorithms
66
* @problem.severity error
7-
* @precision high
87
* @tags cbom
98
* cryptography
109
*/

cpp/ql/src/experimental/cryptography/inventory/new_models/AsymmetricEncryptionAlgorithms.ql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
* @kind problem
55
* @id cpp/quantum-readiness/cbom/all-asymmetric-encryption-algorithms
66
* @problem.severity error
7-
* @precision high
87
* @tags cbom
98
* cryptography
109
*/

cpp/ql/src/experimental/cryptography/inventory/new_models/AuthenticatedEncryptionAlgorithms.ql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
* @kind problem
55
* @id cpp/quantum-readiness/cbom/authenticated-encryption-algorithms
66
* @problem.severity error
7-
* @precision high
87
* @tags cbom
98
* cryptography
109
*/

0 commit comments

Comments
 (0)