Compare commits

..

7 Commits

Author SHA1 Message Date
Alex Eyers-Taylor
652c048af5 Dataflow: Remove diff from overlay informed dataflow. 2025-08-21 19:49:48 +01:00
Alex Eyers-Taylor
eb31b1c0d3 Jave: Use force local to make parsing local after global regex finding. 2025-08-21 19:49:48 +01:00
Alex Eyers-Taylor
979df35109 QL: make a fastTC overlay_caller. 2025-08-21 19:49:47 +01:00
Jonas Jensen
93e3702555 TEMP: DataFlow: Java-only flow including base
This won't work for other languages until we can annotate a `forceLocal`
call with `local?`.
2025-08-21 19:49:47 +01:00
Jonas Jensen
1f265efac8 DataFlow: overlay-informed flow includes the diff 2025-08-21 19:49:47 +01:00
Jonas Jensen
8616943794 DataFlow:Run overlay-informed if not diff-informed
To ensure good performance, always run data flow overlay-informed unless
the configuration has opted in to being diff-informed. This change
affects only databases with an overlay and therefore has no immediate
production consequences.
2025-08-21 19:49:47 +01:00
Alex Eyers-Taylor
ee2de0170c SSA global annotation 2025-07-25 12:17:17 +01:00
314 changed files with 4822 additions and 7385 deletions

View File

@@ -2,3 +2,10 @@ When reviewing code:
* do not review changes in files with `.expected` extension (they are automatically ensured to be correct).
* in `.ql` and `.qll` files, do not try to review the code itself as you don't understand the programming language
well enough to make comments in these languages. You can still check for typos or comment improvements.
When editing `.ql` and `.qll` files:
* All edited `.ql` and `.qll` files should be autoformatted afterwards using the CodeQL CLI.
* To install and use the CodeQL CLI autoformatter:
1. Download and extract CodeQL CLI: `cd /tmp && curl -L -o codeql-linux64.zip https://github.com/github/codeql-cli-binaries/releases/latest/download/codeql-linux64.zip && unzip -q codeql-linux64.zip`
2. Add to PATH: `export PATH="/tmp/codeql:$PATH"`
3. Run autoformatter: `codeql query format [file] --in-place`

View File

@@ -12,9 +12,6 @@ on:
required: false
default: openssl-3.5.0
permissions:
contents: read
jobs:
build:
strategy:

View File

@@ -14,7 +14,10 @@ jobs:
check:
name: Check framework coverage differences and comment
runs-on: ubuntu-latest
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
if: >
${{ github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Dump GitHub context
env:

View File

@@ -230,7 +230,6 @@ use_repo(
"kotlin-compiler-2.1.0-Beta1",
"kotlin-compiler-2.1.20-Beta1",
"kotlin-compiler-2.2.0-Beta1",
"kotlin-compiler-2.2.20-Beta2",
"kotlin-compiler-embeddable-1.6.0",
"kotlin-compiler-embeddable-1.6.20",
"kotlin-compiler-embeddable-1.7.0",
@@ -243,7 +242,6 @@ use_repo(
"kotlin-compiler-embeddable-2.1.0-Beta1",
"kotlin-compiler-embeddable-2.1.20-Beta1",
"kotlin-compiler-embeddable-2.2.0-Beta1",
"kotlin-compiler-embeddable-2.2.20-Beta2",
"kotlin-stdlib-1.6.0",
"kotlin-stdlib-1.6.20",
"kotlin-stdlib-1.7.0",
@@ -256,7 +254,6 @@ use_repo(
"kotlin-stdlib-2.1.0-Beta1",
"kotlin-stdlib-2.1.20-Beta1",
"kotlin-stdlib-2.2.0-Beta1",
"kotlin-stdlib-2.2.20-Beta2",
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

View File

@@ -1,7 +1,3 @@
## 0.4.14
No user-facing changes.
## 0.4.13
### Bug Fixes

View File

@@ -1,3 +0,0 @@
## 0.4.14
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.14
lastReleaseVersion: 0.4.13

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all
version: 0.4.15-dev
version: 0.4.14-dev
library: true
warnOnImplicitThis: true
dependencies:

View File

@@ -1,7 +1,3 @@
## 0.6.6
No user-facing changes.
## 0.6.5
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.6.6
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.6.6
lastReleaseVersion: 0.6.5

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries
version: 0.6.7-dev
version: 0.6.6-dev
library: false
warnOnImplicitThis: true
groups: [actions, queries]

View File

@@ -1,13 +1,3 @@
## 5.4.0
### New Features
* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory.
### Minor Analysis Improvements
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.
## 5.3.0
### Deprecated APIs

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.

View File

@@ -1,9 +0,0 @@
## 5.4.0
### New Features
* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory.
### Minor Analysis Improvements
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 5.4.0
lastReleaseVersion: 5.3.0

View File

@@ -36,14 +36,4 @@ extensions:
# processthreadsapi.h
- ["", "", False, "CreateThread", "", "", "Argument[@3]", "Argument[2].Parameter[@0]", "value", "manual"]
- ["", "", False, "CreateRemoteThread", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"]
- ["", "", False, "CreateRemoteThreadEx", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"]
# wdm.h
- ["", "", False, "RtlCopyVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
- ["", "", False, "RtlCopyDeviceMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
- ["", "", False, "RtlCopyMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
- ["", "", False, "RtlCopyMemoryNonTemporal", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
- ["", "", False, "RtlCopyUnicodeString", "", "", "Argument[*1].Field[*Buffer]", "Argument[*0].Field[*Buffer]", "value", "manual"]
- ["", "", False, "RtlMoveMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
- ["", "", False, "RtlMoveVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
# winternl.h
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
- ["", "", False, "CreateRemoteThreadEx", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"]

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 5.4.1-dev
version: 5.3.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -15,13 +15,6 @@ class StandardSsa extends SsaHelper {
}
/**
* NOTE: If possible, prefer the SSA classes exposed by the new dataflow
* library:
* ```
* import semmle.code.cpp.dataflow.new.DataFlow
* // use `DataFlow::Ssa::Definition`
* ```
*
* A definition of one or more SSA variables, including phi node definitions.
* An _SSA variable_, as defined in the literature, is effectively the pair of
* an `SsaDefinition d` and a `StackVariable v`, written `(d, v)` in this

View File

@@ -1,5 +1,6 @@
private import cpp
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import DataFlowPrivate
private import DataFlowUtil
private import DataFlowImplCommon as DataFlowImplCommon
@@ -59,7 +60,7 @@ private module VirtualDispatch {
* `resolve` predicate to stitch that information together and resolve the
* call.
*/
abstract Node getDispatchValue();
abstract DataFlow::Node getDispatchValue();
/** Gets a candidate target for this call. */
abstract Function resolve();
@@ -71,13 +72,17 @@ private module VirtualDispatch {
* parameter is true when the search is allowed to continue backwards into
* a parameter; non-recursive callers should pass `_` for `allowFromArg`.
*/
predicate flowsFrom(Node src, boolean allowFromArg) {
predicate flowsFrom(DataFlow::Node src, boolean allowFromArg) {
src = this.getDispatchValue() and allowFromArg = true
or
exists(Node other, boolean allowOtherFromArg | this.flowsFrom(other, allowOtherFromArg) |
exists(DataFlow::Node other, boolean allowOtherFromArg |
this.flowsFrom(other, allowOtherFromArg)
|
// Call argument
exists(DataFlowCall call, Position i |
other.(ParameterNode).isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
other
.(DataFlow::ParameterNode)
.isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
src.(ArgumentNode).argumentOf(call, pragma[only_bind_into](pragma[only_bind_out](i)))
) and
allowOtherFromArg = true and
@@ -91,7 +96,7 @@ private module VirtualDispatch {
allowFromArg = false
or
// Local flow
localFlowStep(src, other) and
DataFlow::localFlowStep(src, other) and
allowFromArg = allowOtherFromArg
or
// Flow from global variable to load.
@@ -154,11 +159,11 @@ private module VirtualDispatch {
private class DataSensitiveExprCall extends DataSensitiveCall {
DataSensitiveExprCall() { not exists(this.getStaticCallTarget()) }
override Node getDispatchValue() { result.asOperand() = this.getCallTargetOperand() }
override DataFlow::Node getDispatchValue() { result.asOperand() = this.getCallTargetOperand() }
override Function resolve() {
exists(FunctionInstruction fi |
this.flowsFrom(instructionNode(fi), _) and
this.flowsFrom(DataFlow::instructionNode(fi), _) and
result = fi.getFunctionSymbol()
) and
(
@@ -181,7 +186,7 @@ private module VirtualDispatch {
)
}
override Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) }
override DataFlow::Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) }
override MemberFunction resolve() {
exists(Class overridingClass |
@@ -208,7 +213,7 @@ private module VirtualDispatch {
pragma[noinline]
private predicate hasFlowFromCastFrom(Class derivedClass) {
exists(ConvertToBaseInstruction toBase |
this.flowsFrom(instructionNode(toBase), _) and
this.flowsFrom(DataFlow::instructionNode(toBase), _) and
derivedClass = toBase.getDerivedClass()
)
}
@@ -265,7 +270,7 @@ private predicate mayBenefitFromCallContext(
exists(InitializeParameterInstruction init |
not exists(call.getStaticCallTarget()) and
init.getEnclosingFunction() = f.getUnderlyingCallable() and
call.flowsFrom(instructionNode(init), _) and
call.flowsFrom(DataFlow::instructionNode(init), _) and
init.getParameter().getIndex() = arg
)
}

View File

@@ -4,7 +4,7 @@ private import semmle.code.cpp.ir.IR
private import DataFlowDispatch
private import semmle.code.cpp.ir.internal.IRCppLanguage
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
private import SsaImpl as Ssa
private import SsaInternals as Ssa
private import DataFlowImplCommon as DataFlowImplCommon
private import codeql.util.Unit
private import Node0ToString
@@ -1982,23 +1982,19 @@ module IteratorFlow {
predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() }
class GuardValue = Void;
class Guard extends Void {
predicate hasValueBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
) {
predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
none()
}
predicate valueControlsBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
predicate controlsBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch
) {
none()
}
}
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue val) {
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
none()
}

View File

@@ -13,7 +13,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
private import DataFlowPrivate
private import ModelUtil
private import SsaImpl as SsaImpl
private import SsaInternals as Ssa
private import DataFlowImplCommon as DataFlowImplCommon
private import codeql.util.Unit
private import Node0ToString
@@ -39,39 +39,38 @@ private newtype TIRDataFlowNode =
TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or
TGlobalLikeVariableNode(GlobalLikeVariable var, int indirectionIndex) {
indirectionIndex =
[getMinIndirectionsForType(var.getUnspecifiedType()) .. SsaImpl::getMaxIndirectionsForType(var.getUnspecifiedType())]
[getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
} or
TPostUpdateNodeImpl(Operand operand, int indirectionIndex) {
operand = any(FieldAddress fa).getObjectAddressOperand() and
indirectionIndex =
[0 .. SsaImpl::countIndirectionsForCppType(SsaImpl::getLanguageType(operand))]
indirectionIndex = [0 .. Ssa::countIndirectionsForCppType(Ssa::getLanguageType(operand))]
or
SsaImpl::isModifiableByCall(operand, indirectionIndex)
Ssa::isModifiableByCall(operand, indirectionIndex)
} or
TSsaSynthNode(SsaImpl::SynthNode n) or
TSsaSynthNode(Ssa::SynthNode n) or
TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
SsaImpl::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
} or
TRawIndirectInstruction0(Node0Impl node, int indirectionIndex) {
not exists(node.asOperand()) and
SsaImpl::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
Ssa::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
} or
TFinalParameterNode(Parameter p, int indirectionIndex) {
exists(SsaImpl::FinalParameterUse use |
exists(Ssa::FinalParameterUse use |
use.getParameter() = p and
use.getIndirectionIndex() = indirectionIndex
)
} or
TFinalGlobalValue(SsaImpl::GlobalUse globalUse) or
TInitialGlobalValue(SsaImpl::GlobalDef globalUse) or
TFinalGlobalValue(Ssa::GlobalUse globalUse) or
TInitialGlobalValue(Ssa::GlobalDef globalUse) or
TBodyLessParameterNodeImpl(Parameter p, int indirectionIndex) {
// Rule out parameters of catch blocks.
not exists(p.getCatchBlock()) and
// We subtract one because `getMaxIndirectionsForType` returns the maximum
// indirection for a glvalue of a given type, and this doesn't apply to
// parameters.
indirectionIndex = [0 .. SsaImpl::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and
indirectionIndex = [0 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and
not any(InitializeParameterInstruction init).getParameter() = p
} or
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn)
@@ -82,7 +81,7 @@ private newtype TIRDataFlowNode =
class FieldAddress extends Operand {
FieldAddressInstruction fai;
FieldAddress() { fai = this.getDef() and not SsaImpl::ignoreOperand(this) }
FieldAddress() { fai = this.getDef() and not Ssa::ignoreOperand(this) }
/** Gets the field associated with this instruction. */
Field getField() { result = fai.getField() }
@@ -127,7 +126,7 @@ predicate conversionFlow(
)
or
additional = true and
SsaImpl::isAdditionalConversionFlow(opFrom, instrTo)
Ssa::isAdditionalConversionFlow(opFrom, instrTo)
)
or
isPointerArith = true and
@@ -184,7 +183,7 @@ class Node extends TIRDataFlowNode {
or
this.asOperand().getUse() = block.getInstruction(i)
or
exists(SsaImpl::SynthNode ssaNode |
exists(Ssa::SynthNode ssaNode |
this.(SsaSynthNode).getSynthNode() = ssaNode and
ssaNode.getBasicBlock() = block and
ssaNode.getIndex() = i
@@ -365,10 +364,10 @@ class Node extends TIRDataFlowNode {
* pointed to by `p`.
*/
Expr asDefinition(boolean uncertain) {
exists(StoreInstruction store, SsaImpl::Definition def |
exists(StoreInstruction store, Ssa::Definition def |
store = this.asInstruction() and
result = asDefinitionImpl(store) and
SsaImpl::defToNode(this, def, _) and
Ssa::defToNode(this, def, _) and
if def.isCertain() then uncertain = false else uncertain = true
)
}
@@ -628,7 +627,7 @@ class OperandNode extends Node, Node0 {
* For example, `stripPointers(int*&)` is `int*` and `stripPointers(int*)` is `int`.
*/
Type stripPointer(Type t) {
result = any(SsaImpl::Indirection ind | ind.getType() = t).getBaseType()
result = any(Ssa::Indirection ind | ind.getType() = t).getBaseType()
or
result = t.(PointerToMemberType).getBaseType()
or
@@ -695,12 +694,12 @@ class PostFieldUpdateNode extends PostUpdateNodeImpl {
* in a data flow graph.
*/
class SsaSynthNode extends Node, TSsaSynthNode {
SsaImpl::SynthNode node;
Ssa::SynthNode node;
SsaSynthNode() { this = TSsaSynthNode(node) }
/** Gets the synthesized SSA node associated with this node. */
SsaImpl::SynthNode getSynthNode() { result = node }
Ssa::SynthNode getSynthNode() { result = node }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
@@ -783,12 +782,12 @@ class SideEffectOperandNode extends Node instanceof IndirectOperand {
* from a function body.
*/
class FinalGlobalValue extends Node, TFinalGlobalValue {
SsaImpl::GlobalUse globalUse;
Ssa::GlobalUse globalUse;
FinalGlobalValue() { this = TFinalGlobalValue(globalUse) }
/** Gets the underlying SSA use. */
SsaImpl::GlobalUse getGlobalUse() { result = globalUse }
Ssa::GlobalUse getGlobalUse() { result = globalUse }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
@@ -815,12 +814,12 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
* a function body.
*/
class InitialGlobalValue extends Node, TInitialGlobalValue {
SsaImpl::GlobalDef globalDef;
Ssa::GlobalDef globalDef;
InitialGlobalValue() { this = TInitialGlobalValue(globalDef) }
/** Gets the underlying SSA definition. */
SsaImpl::GlobalDef getGlobalDef() { result = globalDef }
Ssa::GlobalDef getGlobalDef() { result = globalDef }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
@@ -1289,11 +1288,11 @@ class UninitializedNode extends Node {
LocalVariable v;
UninitializedNode() {
exists(SsaImpl::Definition def, SsaImpl::SourceVariable sv |
exists(Ssa::Definition def, Ssa::SourceVariable sv |
def.getIndirectionIndex() = 0 and
def.getValue().asInstruction() instanceof UninitializedInstruction and
SsaImpl::defToNode(this, def, sv) and
v = sv.getBaseVariable().(SsaImpl::BaseIRVariable).getIRVariable().getAst()
Ssa::defToNode(this, def, sv) and
v = sv.getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst()
)
}
@@ -1723,7 +1722,7 @@ private module Cached {
cached
predicate flowsToBackEdge(Node n) {
exists(Node succ, IRBlock bb1, IRBlock bb2 |
SsaImpl::ssaFlow(n, succ) and
Ssa::ssaFlow(n, succ) and
bb1 = n.getBasicBlock() and
bb2 = succ.getBasicBlock() and
bb1 != bb2 and
@@ -1821,7 +1820,7 @@ private module Cached {
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
(
// Def-use/Use-use flow
SsaImpl::ssaFlow(nodeFrom, nodeTo)
Ssa::ssaFlow(nodeFrom, nodeTo)
or
IteratorFlow::localFlowStep(nodeFrom, nodeTo)
or
@@ -1834,7 +1833,7 @@ private module Cached {
|
simpleOperandLocalFlowStep(iFrom, opTo) and
// Omit when the instruction node also represents the operand.
not iFrom = SsaImpl::getIRRepresentationOfOperand(opTo)
not iFrom = Ssa::getIRRepresentationOfOperand(opTo)
)
or
// Indirect operand -> (indirect) instruction flow
@@ -1907,7 +1906,7 @@ private module Cached {
// We also want a write coming out of an `OutNode` to flow `nodeTo`.
// This is different from `reverseFlowInstruction` since `nodeFrom` can never
// be an `OutNode` when it's defined by an instruction.
SsaImpl::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
)
}
@@ -2100,7 +2099,7 @@ private newtype TContent =
TFieldContent(Field f, int indirectionIndex) {
// the indirection index for field content starts at 1 (because `TFieldContent` is thought of as
// the address of the field, `FieldAddress` in the IR).
indirectionIndex = [1 .. SsaImpl::getMaxIndirectionsForType(f.getUnspecifiedType())] and
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(f.getUnspecifiedType())] and
// Reads and writes of union fields are tracked using `UnionContent`.
not f.getDeclaringType() instanceof Union
} or
@@ -2112,9 +2111,7 @@ private newtype TContent =
// field can be read by any read of the union's fields. Again, the indirection index
// is 1-based (because 0 is considered the address).
indirectionIndex =
[1 .. max(SsaImpl::getMaxIndirectionsForType(getAFieldWithSize(u, bytes)
.getUnspecifiedType())
)]
[1 .. max(Ssa::getMaxIndirectionsForType(getAFieldWithSize(u, bytes).getUnspecifiedType()))]
)
} or
TElementContent(int indirectionIndex) {
@@ -2357,7 +2354,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
controls(g, result, edge)
)
or
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
result = Ssa::BarrierGuard<guardChecksNode/3>::getABarrierNode()
}
/**
@@ -2456,7 +2453,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
)
or
result =
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
Ssa::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
}
}
@@ -2493,7 +2490,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
controls(g, result, edge)
)
or
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
result = Ssa::BarrierGuard<guardChecksNode/3>::getABarrierNode()
}
bindingset[value, n]
@@ -2523,7 +2520,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
)
or
result =
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
Ssa::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
}
}
@@ -2579,16 +2576,3 @@ Function getARuntimeTarget(Call call) {
result = DataFlowImplCommon::viableCallableLambda(dfCall, _).asSourceCallable()
)
}
/** A module that provides static single assignment (SSA) information. */
module Ssa {
class Definition = SsaImpl::Definition;
class ExplicitDefinition = SsaImpl::ExplicitDefinition;
class DirectExplicitDefinition = SsaImpl::DirectExplicitDefinition;
class IndirectExplicitDefinition = SsaImpl::IndirectExplicitDefinition;
class PhiNode = SsaImpl::PhiNode;
}

View File

@@ -4,15 +4,15 @@
*/
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
private import semmle.code.cpp.ir.dataflow.DataFlow
private import DataFlowUtil
private import DataFlowPrivate
private import SsaImpl as Ssa
private import SsaInternals as Ssa
/**
* Gets the instruction that goes into `input` for `call`.
*/
Node callInput(CallInstruction call, FunctionInput input) {
DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
// An argument or qualifier
exists(int index |
result.asOperand() = call.getArgumentOperand(index) and
@@ -62,8 +62,8 @@ Node callOutput(CallInstruction call, FunctionOutput output) {
result = callOutputWithIndirectionIndex(call, output, _)
}
Node callInput(CallInstruction call, FunctionInput input, int d) {
exists(Node n | n = callInput(call, input) and d > 0 |
DataFlow::Node callInput(CallInstruction call, FunctionInput input, int d) {
exists(DataFlow::Node n | n = callInput(call, input) and d > 0 |
// An argument or qualifier
hasOperandAndIndex(result, n.asOperand(), d)
or
@@ -85,7 +85,7 @@ private IndirectReturnOutNode getIndirectReturnOutNode(CallInstruction call, int
*/
bindingset[d]
Node callOutput(CallInstruction call, FunctionOutput output, int d) {
exists(Node n, int indirectionIndex |
exists(DataFlow::Node n, int indirectionIndex |
n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and d > 0
|
// The return value

View File

@@ -1,6 +1,6 @@
private import cpp
private import semmle.code.cpp.ir.IR
private import SsaImpl as Ssa
private import SsaInternals as Ssa
/**
* A property provider that hides all instructions and operands that are not relevant for IR dataflow.

View File

@@ -2,7 +2,7 @@ private import cpp
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
private import SsaImpl as Ssa
private import SsaInternals as Ssa
private import PrintIRUtilities
/**

View File

@@ -1,4 +1,4 @@
private import codeql.ssa.Ssa as Ssa
private import codeql.ssa.Ssa as SsaImplCommon
private import semmle.code.cpp.ir.IR
private import DataFlowUtil
private import DataFlowImplCommon as DataFlowImplCommon
@@ -12,7 +12,7 @@ private import semmle.code.cpp.ir.internal.IRCppLanguage
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedInitialization
private import DataFlowPrivate
import SsaImplCommon
import SsaInternalsCommon
private module SourceVariables {
cached
@@ -884,7 +884,7 @@ private predicate baseSourceVariableIsGlobal(
)
}
private module SsaInput implements Ssa::InputSig<Location> {
private module SsaInput implements SsaImplCommon::InputSig<Location> {
import InputSigCommon
import SourceVariables
@@ -958,11 +958,9 @@ class GlobalDef extends Definition {
GlobalLikeVariable getVariable() { result = impl.getVariable() }
}
private module SsaImpl = Ssa::Make<Location, SsaInput>;
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig {
private import codeql.util.Boolean
class Expr extends Instruction {
Expr() {
exists(IRBlock bb, int i |
@@ -994,14 +992,10 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
result instanceof FalseEdge
}
class GuardValue = Boolean;
class Guard instanceof IRGuards::IRGuardCondition {
string toString() { result = super.toString() }
predicate hasValueBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
) {
predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
exists(EdgeKind kind |
super.getBlock() = bb1 and
kind = getConditionalEdge(branch) and
@@ -1009,14 +1003,12 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
)
}
predicate valueControlsBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
) {
this.hasValueBranchEdge(bb1, bb2, branch)
predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
this.hasBranchEdge(bb1, bb2, branch)
}
}
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue branch) {
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
}
@@ -1045,8 +1037,7 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
}
private predicate guardChecks(
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def,
DataFlowIntegrationInput::GuardValue branch, int indirectionIndex
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, boolean branch, int indirectionIndex
) {
exists(UseImpl use |
guardChecksNode(g, use.getNode(), branch, indirectionIndex) and
@@ -1125,11 +1116,9 @@ class PhiNode extends Definition instanceof SsaImpl::PhiNode {
/** An static single assignment (SSA) definition. */
class Definition extends SsaImpl::Definition {
private Definition getAPhiInputOrPriorDefinition() {
result = this.(PhiNode).getAnInput()
or
SsaImpl::uncertainWriteDefinitionInput(this, result)
}
// TODO: Include prior definitions of uncertain writes or rename predicate
// i.e. the disjunct `SsaImpl::uncertainWriteDefinitionInput(this, result)`
private Definition getAPhiInputOrPriorDefinition() { result = this.(PhiNode).getAnInput() }
/**
* Gets a definition that ultimately defines this SSA definition and is
@@ -1140,36 +1129,6 @@ class Definition extends SsaImpl::Definition {
not result instanceof PhiNode
}
/** Gets an `Operand` that represents a use of this definition. */
Operand getAUse() {
exists(SourceVariable sv, IRBlock bb, int i, UseImpl use |
ssaDefReachesRead(sv, this, bb, i) and
use.hasIndexInBlock(bb, i, sv) and
result = use.getNode().asOperand()
)
}
/**
* Gets an `Operand` that represents an indirect use of this definition.
*
* The use is indirect because the operand represents a pointer that points
* to the value written by this definition. For example in:
* ```cpp
* 1. int x = 42;
* 2. int* p = &x;
* ```
* There is an `ExplicitDefinition` corresponding to `x = 42` on line 1 and
* the definition has an indirect use on line 2 because `&x` points to the
* value that was defined by the definition.
*/
Operand getAnIndirectUse(int indirectionIndex) {
exists(SourceVariable sv, IRBlock bb, int i, UseImpl use |
ssaDefReachesRead(sv, this, bb, i) and
use.hasIndexInBlock(bb, i, sv) and
result = use.getNode().asIndirectOperand(indirectionIndex)
)
}
/**
* INTERNAL: Do not use.
*/
@@ -1202,63 +1161,4 @@ class Definition extends SsaImpl::Definition {
Type getUnspecifiedType() { result = this.getUnderlyingType().getUnspecifiedType() }
}
/**
* An SSA definition that corresponds to an explicit definition.
*/
class ExplicitDefinition extends Definition, SsaImpl::WriteDefinition {
DefImpl def;
ExplicitDefinition() {
exists(IRBlock bb, int i, SourceVariable sv |
this.definesAt(sv, bb, i) and
def.hasIndexInBlock(sv, bb, i)
)
}
/**
* Gets the `Instruction` computing the value that is written to the
* associated SSA variable by this SSA definition.
*
* If `this.getIndirectionIndex() = 0` (i.e., if `this` is an instance of
* `DirectExplicitDefinition`) then the SSA variable is present in the source
* code.
* However, if `this.getIndirectionIndex() > 0` (i.e., if `this` is an
* instance of `IndirectExplicitDefinition`) then the SSA variable associated
* with this definition represents the memory pointed to by a variable in the
* source code.
*/
Instruction getAssignedInstruction() { result = def.getValue().asInstruction() }
}
/**
* An explicit SSA definition that writes an indirect value to a pointer.
*
* For example in:
* ```cpp
* int x = 42; // (1)
* int* p = &x; // (2)
* ```
* There are three `ExplicitDefinition`:
* 1. A `DirectExplicitDefinition` at (1) which writes `42` to the SSA variable
* corresponding to `x`.
* 2. A `DirectExplicitDefinition` at (2) which writes `&x` to the SSA variable
* corresponding to `p`.
* 3. A `IndirectExplicitDefinition` at (2) which writes `*&x` (i.e., `x`) to
* the SSA variable corresponding to `*p`.
*/
class IndirectExplicitDefinition extends ExplicitDefinition {
IndirectExplicitDefinition() { this.getIndirectionIndex() > 0 }
}
/**
* An SSA definition that corresponds to an explicit definition.
*
* Unlike `ExplicitDefinition` this class does not include indirect
* explicit definition. See `IndirectExplicitDefinition` if you want to include
* those.
*/
class DirectExplicitDefinition extends ExplicitDefinition {
DirectExplicitDefinition() { this.getIndirectionIndex() = 0 }
}
import SsaCached

View File

@@ -5,7 +5,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.SideEffect
private import DataFlowUtil
private import DataFlowPrivate
private import SsaImpl as Ssa
private import SsaInternals as Ssa
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
private import semmle.code.cpp.ir.dataflow.FlowSteps

View File

@@ -1,9 +1,3 @@
## 1.4.5
### Minor Analysis Improvements
* The "Initialization code not run" query (`cpp/initialization-not-run`) no longer reports an alert on static global variables that have no dereference.
## 1.4.4
### Minor Analysis Improvements

View File

@@ -32,18 +32,9 @@ predicate called(Function f) {
exists(FunctionAccess fa | fa.getTarget() = f)
}
predicate staticWithoutDereference(GlobalVariable v) {
v.isStatic() and
not exists(VariableAccess va |
va = v.getAnAccess() and
dereferenced(va)
)
}
from GlobalVariable v
where
global(v) and
not staticWithoutDereference(v) and
not exists(VariableAccess lval |
v.getAnAccess() = lval and
lval.isUsedAsLValue() and

View File

@@ -1,5 +0,0 @@
## 1.4.5
### Minor Analysis Improvements
* The "Initialization code not run" query (`cpp/initialization-not-run`) no longer reports an alert on static global variables that have no dereference.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.4.5
lastReleaseVersion: 1.4.4

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 1.4.6-dev
version: 1.4.5-dev
groups:
- cpp
- queries

View File

@@ -21,22 +21,14 @@ models
| 20 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
| 21 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
| 22 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
| 23 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 24 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 25 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 26 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
| 27 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 28 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
| 29 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 30 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 31 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
| 32 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
| 33 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
| 34 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
| 35 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
| 36 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
| 23 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
| 24 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
| 25 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
| 26 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
| 27 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
| 28 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
edges
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:36 |
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:28 |
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:17 |
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:17 Sink:MaD:2 |
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
@@ -45,10 +37,10 @@ edges
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:36 |
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:34 |
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:33 |
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:35 |
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:28 |
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:26 |
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:25 |
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:27 |
| test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | |
| test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:16 |
@@ -60,15 +52,15 @@ edges
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | |
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:1 |
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | |
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:34 |
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:26 |
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | |
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:1 |
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | |
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:33 |
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:25 |
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | |
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:1 |
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | |
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:35 |
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:27 |
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:1 |
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | |
@@ -76,16 +68,16 @@ edges
| test.cpp:46:30:46:32 | *arg [x] | test.cpp:47:12:47:19 | *arg [x] | provenance | |
| test.cpp:47:12:47:19 | *arg [x] | test.cpp:48:13:48:13 | *s [x] | provenance | |
| test.cpp:48:13:48:13 | *s [x] | test.cpp:48:16:48:16 | x | provenance | Sink:MaD:1 |
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:32 |
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:24 |
| test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | |
| test.cpp:56:2:56:2 | *s [post update] [x] | test.cpp:59:55:59:64 | *& ... [x] | provenance | |
| test.cpp:56:2:56:18 | ... = ... | test.cpp:56:2:56:2 | *s [post update] [x] | provenance | |
| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:16 |
| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | provenance | |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:68:22:68:22 | y | provenance | |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:74:22:74:22 | y | provenance | |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:82:22:82:22 | y | provenance | |
@@ -188,59 +180,6 @@ edges
| windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | provenance | |
| windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | provenance | |
| windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | provenance | |
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:27 |
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:23 |
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:24 |
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:25 |
| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | provenance | |
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:26 |
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | provenance | |
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | provenance | |
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:29 |
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:30 |
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:28 |
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | provenance | |
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:533:11:533:16 | call to source | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:537:40:537:41 | *& ... | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:542:38:542:39 | *& ... | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:547:32:547:33 | *& ... | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:552:43:552:44 | *& ... | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:568:32:568:33 | *& ... | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:573:40:573:41 | *& ... | provenance | |
| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | windows.cpp:538:10:538:23 | access to array | provenance | |
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | provenance | |
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:27 |
| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | windows.cpp:543:10:543:23 | access to array | provenance | |
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | provenance | |
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:23 |
| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | windows.cpp:548:10:548:23 | access to array | provenance | |
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | provenance | |
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:24 |
| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | windows.cpp:553:10:553:23 | access to array | provenance | |
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | provenance | |
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:25 |
| windows.cpp:559:5:559:24 | ... = ... | windows.cpp:561:39:561:44 | *buffer | provenance | |
| windows.cpp:559:17:559:24 | call to source | windows.cpp:559:5:559:24 | ... = ... | provenance | |
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:562:10:562:19 | *src_string [*Buffer] | provenance | |
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:563:40:563:50 | *& ... [*Buffer] | provenance | |
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | provenance | |
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:28 |
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:10:562:29 | access to array | provenance | |
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:21:562:26 | *Buffer | provenance | |
| windows.cpp:562:21:562:26 | *Buffer | windows.cpp:562:10:562:29 | access to array | provenance | |
| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | windows.cpp:564:10:564:20 | *dest_string [*Buffer] | provenance | |
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | provenance | |
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:26 |
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:10:564:30 | access to array | provenance | |
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:22:564:27 | *Buffer | provenance | |
| windows.cpp:564:22:564:27 | *Buffer | windows.cpp:564:10:564:30 | access to array | provenance | |
| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | windows.cpp:569:10:569:23 | access to array | provenance | |
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | provenance | |
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:29 |
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | windows.cpp:574:10:574:23 | access to array | provenance | |
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | provenance | |
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:30 |
nodes
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer |
| asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer |
@@ -413,59 +352,6 @@ nodes
| windows.cpp:439:7:439:8 | *& ... [x] | semmle.label | *& ... [x] |
| windows.cpp:451:7:451:8 | *& ... [x] | semmle.label | *& ... [x] |
| windows.cpp:464:7:464:8 | *& ... [x] | semmle.label | *& ... [x] |
| windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | semmle.label | [summary param] *0 in RtlCopyVolatileMemory [Return] |
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | semmle.label | [summary param] *1 in RtlCopyVolatileMemory |
| windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | semmle.label | [summary param] *0 in RtlCopyDeviceMemory [Return] |
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | semmle.label | [summary param] *1 in RtlCopyDeviceMemory |
| windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | semmle.label | [summary param] *0 in RtlCopyMemory [Return] |
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | semmle.label | [summary param] *1 in RtlCopyMemory |
| windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | semmle.label | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] |
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | semmle.label | [summary param] *1 in RtlCopyMemoryNonTemporal |
| windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | semmle.label | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] |
| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | semmle.label | [summary param] *1 in RtlCopyUnicodeString [*Buffer] |
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | semmle.label | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString |
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | semmle.label | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] |
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | semmle.label | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString |
| windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | semmle.label | [summary param] *0 in RtlMoveMemory [Return] |
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | semmle.label | [summary param] *1 in RtlMoveMemory |
| windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | semmle.label | [summary param] *0 in RtlMoveVolatileMemory [Return] |
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | semmle.label | [summary param] *1 in RtlMoveVolatileMemory |
| windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | semmle.label | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] |
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | semmle.label | [summary param] *1 in RtlInitUnicodeString |
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | semmle.label | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] |
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | semmle.label | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString |
| windows.cpp:533:11:533:16 | call to source | semmle.label | call to source |
| windows.cpp:533:11:533:16 | call to source | semmle.label | call to source |
| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | semmle.label | RtlCopyVolatileMemory output argument |
| windows.cpp:537:40:537:41 | *& ... | semmle.label | *& ... |
| windows.cpp:538:10:538:23 | access to array | semmle.label | access to array |
| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | semmle.label | RtlCopyDeviceMemory output argument |
| windows.cpp:542:38:542:39 | *& ... | semmle.label | *& ... |
| windows.cpp:543:10:543:23 | access to array | semmle.label | access to array |
| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | semmle.label | RtlCopyMemory output argument |
| windows.cpp:547:32:547:33 | *& ... | semmle.label | *& ... |
| windows.cpp:548:10:548:23 | access to array | semmle.label | access to array |
| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | semmle.label | RtlCopyMemoryNonTemporal output argument |
| windows.cpp:552:43:552:44 | *& ... | semmle.label | *& ... |
| windows.cpp:553:10:553:23 | access to array | semmle.label | access to array |
| windows.cpp:559:5:559:24 | ... = ... | semmle.label | ... = ... |
| windows.cpp:559:17:559:24 | call to source | semmle.label | call to source |
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | semmle.label | RtlInitUnicodeString output argument [*Buffer] |
| windows.cpp:561:39:561:44 | *buffer | semmle.label | *buffer |
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | semmle.label | *src_string [*Buffer] |
| windows.cpp:562:10:562:29 | access to array | semmle.label | access to array |
| windows.cpp:562:21:562:26 | *Buffer | semmle.label | *Buffer |
| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | semmle.label | RtlCopyUnicodeString output argument [*Buffer] |
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | semmle.label | *& ... [*Buffer] |
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | semmle.label | *dest_string [*Buffer] |
| windows.cpp:564:10:564:30 | access to array | semmle.label | access to array |
| windows.cpp:564:22:564:27 | *Buffer | semmle.label | *Buffer |
| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | semmle.label | RtlMoveMemory output argument |
| windows.cpp:568:32:568:33 | *& ... | semmle.label | *& ... |
| windows.cpp:569:10:569:23 | access to array | semmle.label | access to array |
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | semmle.label | RtlMoveVolatileMemory output argument |
| windows.cpp:573:40:573:41 | *& ... | semmle.label | *& ... |
| windows.cpp:574:10:574:23 | access to array | semmle.label | access to array |
subpaths
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer |
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual |
@@ -473,12 +359,4 @@ subpaths
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body |
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument |
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument |
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | windows.cpp:547:19:547:29 | RtlCopyMemory output argument |
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument |
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] |
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] |
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | windows.cpp:568:19:568:29 | RtlMoveMemory output argument |
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument |
testFailures

View File

@@ -5556,24 +5556,12 @@
| Dubious signature "(z_streamp,int *)" in summary model. |
| Dubious signature "(z_streamp,unsigned int *,int *)" in summary model. |
| Dubious signature "(z_streamp,unsigned int)" in summary model. |
| Unrecognized input specification "Argument[***0]" in summary model. |
| Unrecognized input specification "Argument[***1]" in summary model. |
| Unrecognized input specification "Argument[***3]" in summary model. |
| Unrecognized input specification "Argument[***4]" in summary model. |
| Unrecognized input specification "Argument[****0]" in summary model. |
| Unrecognized input specification "Argument[****1]" in summary model. |
| Unrecognized input specification "Argument[****3]" in summary model. |
| Unrecognized input specification "Argument[****4]" in summary model. |
| Unrecognized input specification "Argument[*****0]" in summary model. |
| Unrecognized input specification "Argument[*****1]" in summary model. |
| Unrecognized input specification "Field[****hEvent]" in summary model. |
| Unrecognized input specification "Field[***hEvent]" in summary model. |
| Unrecognized output specification "Argument[***0]" in summary model. |
| Unrecognized output specification "Argument[***1]" in summary model. |
| Unrecognized output specification "Argument[****0]" in summary model. |
| Unrecognized output specification "Argument[****1]" in summary model. |
| Unrecognized output specification "Argument[*****0]" in summary model. |
| Unrecognized output specification "Argument[*****1]" in summary model. |
| Unrecognized output specification "Field[****hEvent]" in summary model. |
| Unrecognized output specification "Field[***hEvent]" in summary model. |
| Unrecognized output specification "Parameter[***0]" in summary model. |

View File

@@ -466,111 +466,4 @@ void test_create_thread()
&attrList,
&threadId);
}
}
using size_t = decltype(sizeof(0));
volatile void * RtlCopyVolatileMemory(
volatile void *Destination,
volatile const void *Source,
size_t Length
);
volatile void * RtlCopyDeviceMemory(
volatile void *Destination,
volatile const void *Source,
size_t Length
);
void RtlCopyMemory(
void* Destination,
const void* Source,
size_t Length
);
using VOID = void;
VOID RtlCopyMemoryNonTemporal(
VOID *Destination,
const VOID *Source,
SIZE_T Length
);
using USHORT = unsigned short;
using PWSTR = wchar_t*;
using PCWSTR = const wchar_t*;
using PCUNICODE_STRING = const struct _UNICODE_STRING*;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
VOID RtlCopyUnicodeString(
PUNICODE_STRING DestinationString,
PCUNICODE_STRING SourceString
);
void RtlMoveMemory(
void* Destination,
const void* Source,
size_t Length
);
volatile void * RtlMoveVolatileMemory(
volatile void *Destination,
volatile const void *Source,
size_t Length
);
void RtlInitUnicodeString(
PUNICODE_STRING DestinationString,
PCWSTR SourceString
);
void test_copy_and_move_memory() {
int x = source();
{
char dest_buffer[1024];
RtlCopyVolatileMemory(dest_buffer, &x, sizeof(x));
sink(dest_buffer[0]); // $ ir
}
{
char dest_buffer[1024];
RtlCopyDeviceMemory(dest_buffer, &x, sizeof(x));
sink(dest_buffer[0]); // $ ir
}
{
char dest_buffer[1024];
RtlCopyMemory(dest_buffer, &x, sizeof(x));
sink(dest_buffer[0]); // $ ir
}
{
char dest_buffer[1024];
RtlCopyMemoryNonTemporal(dest_buffer, &x, sizeof(x));
sink(dest_buffer[0]); // $ ir
}
{
UNICODE_STRING dest_string;
UNICODE_STRING src_string;
wchar_t buffer[1024];
buffer[0] = source();
RtlInitUnicodeString(&src_string, buffer);
sink(src_string.Buffer[0]); // $ ir
RtlCopyUnicodeString(&dest_string, &src_string);
sink(dest_string.Buffer[0]); // $ ir
}
{
char dest_buffer[1024];
RtlMoveMemory(dest_buffer, &x, sizeof(x));
sink(dest_buffer[0]); // $ ir
}
{
volatile char dest_buffer[1024];
RtlMoveVolatileMemory(dest_buffer, &x, sizeof(x));
sink(dest_buffer[0]); // $ ir
}
}

View File

@@ -1,2 +0,0 @@
| test.cpp:12:16:12:17 | g1 | Initialization code for 'g1' is never run. |
| test.cpp:14:23:14:24 | g3 | Initialization code for 'g3' is never run. |

View File

@@ -1 +0,0 @@
Critical/InitialisationNotRun.ql

View File

@@ -1,36 +0,0 @@
// --- stubs ---
char *strcpy(char *dest, const char *src);
// --- tests ---
class GlobalStorage {
public:
char name[1000];
};
GlobalStorage *g1; // BAD
static GlobalStorage g2; // GOOD
static GlobalStorage *g3; // BAD
// static variables are initialized by compilers
static int a; // GOOD
static int b = 0; // GOOD
void init() { //initializes g_storage, but is never run from main
g1 = new GlobalStorage();
g3 = new GlobalStorage();
}
void init2(int b) {
for (int i = 0; i < b; ++i)
a *= -1;
}
int main(int argc, char *argv[]) {
//init not called
strcpy(g1->name, argv[1]); // g1 is used before init() is called
strcpy(g2.name, argv[1]); // g2 is initialised by compiler
strcpy(g3->name, argv[1]);
b++;
return 0;
}

View File

@@ -1,7 +1,3 @@
## 1.7.45
No user-facing changes.
## 1.7.44
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 1.7.45
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.45
lastReleaseVersion: 1.7.44

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.7.46-dev
version: 1.7.45-dev
groups:
- csharp
- solorigate

View File

@@ -1,7 +1,3 @@
## 1.7.45
No user-facing changes.
## 1.7.44
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 1.7.45
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.45
lastReleaseVersion: 1.7.44

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.7.46-dev
version: 1.7.45-dev
groups:
- csharp
- solorigate

View File

@@ -1,7 +1,3 @@
## 5.2.1
No user-facing changes.
## 5.2.0
### New Features

View File

@@ -1,3 +0,0 @@
## 5.2.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 5.2.1
lastReleaseVersion: 5.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 5.2.2-dev
version: 5.2.1-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp

View File

@@ -201,7 +201,7 @@ class ValueOrRefType extends Type, Attributable, @value_or_ref_type {
*/
pragma[inline]
predicate hasCallable(Callable c) {
this.hasMember(c)
this.hasMethod(c)
or
this.hasMember(c.(Accessor).getDeclaration())
}

View File

@@ -975,8 +975,7 @@ private module Cached {
cached // nothing is actually cached
module BarrierGuard<guardChecksSig/3 guardChecks> {
private predicate guardChecksAdjTypes(
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e,
DataFlowIntegrationInput::GuardValue branch
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
) {
exists(Guards::AbstractValues::BooleanValue v |
guardChecks(g, e.getAstNode(), v) and
@@ -1017,7 +1016,6 @@ string getToStringPrefix(Definition def) {
private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig {
private import csharp as Cs
private import semmle.code.csharp.controlflow.BasicBlocks
private import codeql.util.Boolean
class Expr extends ControlFlow::Node {
predicate hasCfgNode(ControlFlow::BasicBlock bb, int i) { this = bb.getNode(i) }
@@ -1044,14 +1042,12 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
)
}
class GuardValue = Boolean;
class Guard extends Guards::Guard {
/**
* Holds if the evaluation of this guard to `branch` corresponds to the edge
* from `bb1` to `bb2`.
*/
predicate hasValueBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue branch) {
predicate hasBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
exists(ControlFlow::SuccessorTypes::ConditionalSuccessor s |
this.getAControlFlowNode() = bb1.getLastNode() and
bb2 = bb1.getASuccessorByType(s) and
@@ -1064,13 +1060,13 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
* branch edge from `bb1` to `bb2`. That is, following the edge from
* `bb1` to `bb2` implies that this guard evaluated to `branch`.
*/
predicate valueControlsBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue branch) {
this.hasValueBranchEdge(bb1, bb2, branch)
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
this.hasBranchEdge(bb1, bb2, branch)
}
}
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, GuardValue branch) {
predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) {
exists(ConditionBlock conditionBlock, ControlFlow::SuccessorTypes::ConditionalSuccessor s |
guard.getAControlFlowNode() = conditionBlock.getLastNode() and
s.getValue() = branch and

View File

@@ -1,7 +1,3 @@
## 1.3.2
No user-facing changes.
## 1.3.1
### Minor Analysis Improvements

View File

@@ -1,3 +0,0 @@
## 1.3.2
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.3.2
lastReleaseVersion: 1.3.1

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 1.3.3-dev
version: 1.3.2-dev
groups:
- csharp
- queries

View File

@@ -21,7 +21,7 @@
Java,"Java 7 to 24 [6]_","javac (OpenJDK and Oracle JDK),
Eclipse compiler for Java (ECJ) [7]_",``.java``
Kotlin,"Kotlin 1.6.0 to 2.2.2\ *x*","kotlinc",``.kt``
Kotlin,"Kotlin 1.6.0 to 2.2.0\ *x*","kotlinc",``.kt``
JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [8]_"
Python [9]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13",Not applicable,``.py``
Ruby [10]_,"up to 3.3",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"

View File

@@ -1,7 +1,3 @@
## 1.0.28
No user-facing changes.
## 1.0.27
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 1.0.28
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.0.28
lastReleaseVersion: 1.0.27

View File

@@ -1,5 +1,5 @@
name: codeql-go-consistency-queries
version: 1.0.29-dev
version: 1.0.28-dev
groups:
- go
- queries

View File

@@ -1,7 +1,3 @@
## 4.3.1
No user-facing changes.
## 4.3.0
### Deprecated APIs

View File

@@ -1,3 +0,0 @@
## 4.3.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 4.3.1
lastReleaseVersion: 4.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/go-all
version: 4.3.2-dev
version: 4.3.1-dev
groups: go
dbscheme: go.dbscheme
extractor: go

View File

@@ -1,7 +1,3 @@
## 1.4.2
No user-facing changes.
## 1.4.1
### Minor Analysis Improvements

View File

@@ -1,3 +0,0 @@
## 1.4.2
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.4.2
lastReleaseVersion: 1.4.1

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries
version: 1.4.3-dev
version: 1.4.2-dev
groups:
- go
- queries

View File

@@ -83,7 +83,7 @@ kt_javac_options(
"kotlin.RequiresOptIn",
"org.jetbrains.kotlin.ir.symbols.%s" %
("IrSymbolInternals" if version_less(v, "2.0.0") else "UnsafeDuringIrConstructionAPI"),
] + ([] if version_less(v, "2.2.20") else ["org.jetbrains.kotlin.DeprecatedForRemovalCompilerApi"]),
],
x_suppress_version_warnings = True,
),
# * extractor.name is different for each version, so we need to put it in different output dirs

Binary file not shown.

Binary file not shown.

View File

@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability
import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.NameUtils
import org.jetbrains.kotlin.name.SpecialNames

View File

@@ -1,9 +0,0 @@
package com.github.codeql.utils.versions
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor
fun getJvmModuleNameForDeserializedDescriptor(descriptor: CallableMemberDescriptor): String? {
return org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor(descriptor)
}

View File

@@ -1,32 +0,0 @@
package com.github.codeql.utils.versions
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.metadata.deserialization.*
import org.jetbrains.kotlin.metadata.jvm.deserialization.*
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
import org.jetbrains.kotlin.resolve.DescriptorUtils.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
fun getJvmModuleNameForDeserializedDescriptor(descriptor: CallableMemberDescriptor): String? {
val parent = getParentOfType(descriptor, ClassOrPackageFragmentDescriptor::class.java, false)
when {
parent is DeserializedClassDescriptor -> {
val classProto = parent.classProto
val nameResolver = parent.c.nameResolver
return classProto.getExtensionOrNull(JvmProtoBuf.classModuleName)
?.let(nameResolver::getString)
?: JvmProtoBufUtil.DEFAULT_MODULE_NAME
}
descriptor is DeserializedMemberDescriptor -> {
val source = descriptor.containerSource
if (source is JvmPackagePartSource) {
return source.moduleName
}
}
}
return null
}

View File

@@ -12,7 +12,6 @@ VERSIONS = [
"2.1.0-Beta1",
"2.1.20-Beta1",
"2.2.0-Beta1",
"2.2.20-Beta2",
]
def _version_to_tuple(v):

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 2.2.30.",
"markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 2.2.10.",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,6 +1,6 @@
extensions:
- addsTo:
pack: codeql/java-all
pack: codeql/java-queries
extensible: extractorInformationSkipKey
data:
# These will have unstable values, as they are dependent on the

View File

@@ -1,6 +1,6 @@
extensions:
- addsTo:
pack: codeql/java-all
pack: codeql/java-queries
extensible: extractorInformationSkipKey
data:
# These will have unstable values, as they are dependent on the

View File

@@ -1,9 +1,3 @@
## 7.5.0
### New Features
* Kotlin versions up to 2.2.2\ *x* are now supported.
## 7.4.0
### Deprecated APIs
@@ -16,7 +10,7 @@
### New Features
* You can now add sinks for the query "Deserialization of user-controlled data" (`java/unsafe-deserialization`) using [data extensions](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-java-and-kotlin/#extensible-predicates-used-to-create-custom-models-in-java-and-kotlin) by extending `sinkModel` and using the kind "unsafe-deserialization". The existing sinks that do not require extra logic to determine if they are unsafe are now defined in this way.
* You can now add sinks for the query "Deserialization of user-controlled data" (`java/unsafe-deserialization`) using [data extensions](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-java-and-kotlin/#extensible-predicates-used-to-create-custom-models-in-java-and-kotlin) by extending `sinkModel` and using the kind "unsafe-deserialization". The existing sinks which do not require extra logic to determine if they are unsafe are now defined in this way.
### Minor Analysis Improvements

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Guard implication logic involving wrapper methods has been improved. In particular, this means fewer false positives for `java/dereferenced-value-may-be-null`.

View File

@@ -1,5 +0,0 @@
## 7.5.0
### New Features
* Kotlin versions up to 2.2.2\ *x* are now supported.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 7.5.0
lastReleaseVersion: 7.4.0

View File

@@ -1,5 +1,5 @@
name: codeql/java-all
version: 7.5.1-dev
version: 7.4.1-dev
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java

View File

@@ -61,9 +61,3 @@ class Diagnostic extends @diagnostic {
/** Gets a textual representation of this diagnostic. */
string toString() { result = this.getMessage() }
}
/**
* Holds for extraction information keys that should be skipped from telemetry reports.
* This predicate can be extended by other packs to filter out specific telemetry keys.
*/
extensible predicate extractorInformationSkipKey(string key);

View File

@@ -57,7 +57,7 @@ private module Input implements BB::InputSig<Location> {
* Holds if `node` represents an exit node to be used when calculating
* post dominance.
*/
predicate nodeIsPostDominanceExit(Node node) { node instanceof ControlFlow::NormalExitNode }
predicate nodeIsPostDominanceExit(Node node) { node instanceof ControlFlow::ExitNode }
}
private module BbImpl = BB::Make<Location, Input>;

View File

@@ -146,8 +146,6 @@ private module GuardsInput implements SharedGuards::InputSig<Location> {
class ControlFlowNode = J::ControlFlowNode;
class NormalExitNode = ControlFlow::NormalExitNode;
class BasicBlock = J::BasicBlock;
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) { J::dominatingEdge(bb1, bb2) }
@@ -324,55 +322,6 @@ private module GuardsInput implements SharedGuards::InputSig<Location> {
Expr getElse() { result = super.getFalseExpr() }
}
class Parameter = J::Parameter;
private int parameterPosition() { result in [-1, any(Parameter p).getPosition()] }
/** A parameter position represented by an integer. */
class ParameterPosition extends int {
ParameterPosition() { this = parameterPosition() }
}
/** An argument position represented by an integer. */
class ArgumentPosition extends int {
ArgumentPosition() { this = parameterPosition() }
}
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
overlay[caller?]
pragma[inline]
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }
final private class FinalMethod = Method;
class NonOverridableMethod extends FinalMethod {
NonOverridableMethod() { not super.isOverridable() }
Parameter getParameter(ParameterPosition ppos) {
super.getParameter(ppos) = result and
not result.isVarargs()
}
GuardsInput::Expr getAReturnExpr() {
exists(ReturnStmt ret |
this = ret.getEnclosingCallable() and
ret.getResult() = result
)
}
}
private predicate nonOverridableMethodCall(MethodCall call, NonOverridableMethod m) {
call.getMethod().getSourceDeclaration() = m
}
class NonOverridableMethodCall extends GuardsInput::Expr instanceof MethodCall {
NonOverridableMethodCall() { nonOverridableMethodCall(this, _) }
NonOverridableMethod getMethod() { nonOverridableMethodCall(this, result) }
GuardsInput::Expr getArgument(ArgumentPosition apos) { result = super.getArgument(apos) }
}
}
private module GuardsImpl = SharedGuards::Make<Location, GuardsInput>;
@@ -391,17 +340,6 @@ private module LogicInputCommon {
NullGuards::nullCheckMethod(call.getMethod(), val.asBooleanValue(), isNull)
)
}
predicate additionalImpliesStep(
GuardsImpl::PreGuard g1, GuardValue v1, GuardsImpl::PreGuard g2, GuardValue v2
) {
exists(MethodCall check, int argIndex |
g1 = check and
v1.getDualValue().isThrowsException() and
conditionCheckArgument(check, argIndex, v2.asBooleanValue()) and
g2 = check.getArgument(argIndex)
)
}
}
private module LogicInput_v1 implements GuardsImpl::LogicInputSig {
@@ -426,13 +364,18 @@ private module LogicInput_v1 implements GuardsImpl::LogicInputSig {
}
}
predicate parameterDefinition(Parameter p, SsaDefinition def) {
def.(BaseSsaImplicitInit).isParameterDefinition(p)
}
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
predicate additionalImpliesStep = LogicInputCommon::additionalImpliesStep/4;
predicate additionalImpliesStep(
GuardsImpl::PreGuard g1, GuardValue v1, GuardsImpl::PreGuard g2, GuardValue v2
) {
exists(MethodCall check, int argIndex |
g1 = check and
v1.getDualValue().isThrowsException() and
conditionCheckArgument(check, argIndex, v2.asBooleanValue()) and
g2 = check.getArgument(argIndex)
)
}
}
private module LogicInput_v2 implements GuardsImpl::LogicInputSig {
@@ -457,13 +400,15 @@ private module LogicInput_v2 implements GuardsImpl::LogicInputSig {
}
}
predicate parameterDefinition(Parameter p, SsaDefinition def) {
def.(SSA::SsaImplicitInit).isParameterDefinition(p)
}
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
predicate additionalImpliesStep = LogicInputCommon::additionalImpliesStep/4;
predicate additionalImpliesStep(
GuardsImpl::PreGuard g1, GuardValue v1, GuardsImpl::PreGuard g2, GuardValue v2
) {
LogicInput_v1::additionalImpliesStep(g1, v1, g2, v2)
or
CustomGuard::additionalImpliesStep(g1, v1, g2, v2)
}
}
private module LogicInput_v3 implements GuardsImpl::LogicInputSig {
@@ -476,11 +421,70 @@ private module LogicInput_v3 implements GuardsImpl::LogicInputSig {
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
predicate additionalImpliesStep = LogicInputCommon::additionalImpliesStep/4;
predicate additionalImpliesStep = LogicInput_v2::additionalImpliesStep/4;
}
private module CustomGuardInput implements Guards_v2::CustomGuardInputSig {
private import semmle.code.java.dataflow.SSA
private int parameterPosition() { result in [-1, any(Parameter p).getPosition()] }
/** A parameter position represented by an integer. */
class ParameterPosition extends int {
ParameterPosition() { this = parameterPosition() }
}
/** An argument position represented by an integer. */
class ArgumentPosition extends int {
ArgumentPosition() { this = parameterPosition() }
}
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
overlay[caller?]
pragma[inline]
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }
final private class FinalMethod = Method;
class BooleanMethod extends FinalMethod {
BooleanMethod() {
super.getReturnType().(PrimitiveType).hasName("boolean") and
not super.isOverridable()
}
LogicInput_v2::SsaDefinition getParameter(ParameterPosition ppos) {
exists(Parameter p |
super.getParameter(ppos) = p and
not p.isVarargs() and
result.(SsaImplicitInit).isParameterDefinition(p)
)
}
GuardsInput::Expr getAReturnExpr() {
exists(ReturnStmt ret |
this = ret.getEnclosingCallable() and
ret.getResult() = result
)
}
}
private predicate booleanMethodCall(MethodCall call, BooleanMethod m) {
call.getMethod().getSourceDeclaration() = m
}
class BooleanMethodCall extends GuardsInput::Expr instanceof MethodCall {
BooleanMethodCall() { booleanMethodCall(this, _) }
BooleanMethod getMethod() { booleanMethodCall(this, result) }
GuardsInput::Expr getArgument(ArgumentPosition apos) { result = super.getArgument(apos) }
}
}
class GuardValue = GuardsImpl::GuardValue;
private module CustomGuard = Guards_v2::CustomGuard<CustomGuardInput>;
/** INTERNAL: Don't use. */
module Guards_v1 = GuardsImpl::Logic<LogicInput_v1>;

View File

@@ -10,7 +10,7 @@
* of the field in case the field is not amenable to a non-trivial SSA
* representation.
*/
overlay[local?]
overlay[local]
module;
import java

View File

@@ -6,6 +6,7 @@ module;
private import semmle.code.Location
private import codeql.dataflow.DataFlow
private import semmle.code.java.Overlay
module Private {
import DataFlowPrivate
@@ -29,4 +30,6 @@ module JavaDataFlow implements InputSig<Location> {
predicate mayBenefitFromCallContext = Private::mayBenefitFromCallContext/1;
predicate viableImplInCallContext = Private::viableImplInCallContext/2;
predicate isEvaluatingInOverlay = isOverlay/0;
}

View File

@@ -348,16 +348,6 @@ predicate expectsContent(Node n, ContentSet c) {
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c)
}
pragma[nomagic]
private predicate numericRepresentative(RefType t) {
t.(BoxedType).getPrimitiveType().getName() = "double"
}
pragma[nomagic]
private predicate booleanRepresentative(RefType t) {
t.(BoxedType).getPrimitiveType().getName() = "boolean"
}
/**
* Gets a representative (boxed) type for `t` for the purpose of pruning
* possible flow. A single type is used for all numeric types to account for
@@ -366,10 +356,10 @@ private predicate booleanRepresentative(RefType t) {
RefType getErasedRepr(Type t) {
exists(Type e | e = t.getErasure() |
if e instanceof NumericOrCharType
then numericRepresentative(result)
then result.(BoxedType).getPrimitiveType().getName() = "double"
else
if e instanceof BooleanType
then booleanRepresentative(result)
then result.(BoxedType).getPrimitiveType().getName() = "boolean"
else result = e
)
or

View File

@@ -83,6 +83,7 @@ overlay[caller?]
pragma[inline]
predicate localFlow(Node node1, Node node2) { node1 = node2 or localFlowStepPlus(node1, node2) }
overlay[caller?]
private predicate localFlowStepPlus(Node node1, Node node2) = fastTC(localFlowStep/2)(node1, node2)
/**

View File

@@ -1,4 +1,4 @@
overlay[local?]
overlay[local]
module;
import java
@@ -157,15 +157,20 @@ private predicate hasEntryDef(TrackedVar v, BasicBlock b) {
}
/** Holds if `n` might update the locally tracked variable `v`. */
overlay[global]
pragma[nomagic]
private predicate uncertainVariableUpdate(TrackedVar v, ControlFlowNode n, BasicBlock b, int i) {
private predicate uncertainVariableUpdateImpl(TrackedVar v, ControlFlowNode n, BasicBlock b, int i) {
exists(Call c | c = n.asCall() | updatesNamedField(c, v, _)) and
b.getNode(i) = n and
hasDominanceInformation(b)
or
uncertainVariableUpdate(v.getQualifier(), n, b, i)
uncertainVariableUpdateImpl(v.getQualifier(), n, b, i)
}
/** Holds if `n` might update the locally tracked variable `v`. */
predicate uncertainVariableUpdate(TrackedVar v, ControlFlowNode n, BasicBlock b, int i) =
forceLocal(uncertainVariableUpdateImpl/4)(v, n, b, i)
private module SsaInput implements SsaImplCommon::InputSig<Location> {
private import java as J
@@ -345,6 +350,7 @@ private module Cached {
* Constructor --(intraInstanceCallEdge)-->+ Method(setter of this.f)
* ```
*/
overlay[global]
private predicate intraInstanceCallEdge(Callable c1, Method m2) {
exists(MethodCall ma, RefType t1 |
ma.getCaller() = c1 and
@@ -365,6 +371,7 @@ private module Cached {
)
}
overlay[global]
private Callable tgt(Call c) {
result = viableImpl_v2(c)
or
@@ -374,11 +381,13 @@ private module Cached {
}
/** Holds if `(c1,c2)` is an edge in the call graph. */
overlay[global]
private predicate callEdge(Callable c1, Callable c2) {
exists(Call c | c.getCaller() = c1 and c2 = tgt(c))
}
/** Holds if `(c1,c2)` is an edge in the call graph excluding `intraInstanceCallEdge`. */
overlay[global]
private predicate crossInstanceCallEdge(Callable c1, Callable c2) {
callEdge(c1, c2) and not intraInstanceCallEdge(c1, c2)
}
@@ -392,6 +401,7 @@ private module Cached {
relevantFieldUpdate(_, f.getField(), _)
}
overlay[global]
private predicate source(Call call, TrackedField f, Field field, Callable c, boolean fresh) {
relevantCall(call, f) and
field = f.getField() and
@@ -405,9 +415,11 @@ private module Cached {
* `fresh` indicates whether the instance `this` in `c` has been freshly
* allocated along the call-chain.
*/
overlay[global]
private newtype TCallableNode =
MkCallableNode(Callable c, boolean fresh) { source(_, _, _, c, fresh) or edge(_, c, fresh) }
overlay[global]
private predicate edge(TCallableNode n, Callable c2, boolean f2) {
exists(Callable c1, boolean f1 | n = MkCallableNode(c1, f1) |
intraInstanceCallEdge(c1, c2) and f2 = f1
@@ -417,6 +429,7 @@ private module Cached {
)
}
overlay[global]
private predicate edge(TCallableNode n1, TCallableNode n2) {
exists(Callable c2, boolean f2 |
edge(n1, c2, f2) and
@@ -424,6 +437,7 @@ private module Cached {
)
}
overlay[global]
pragma[noinline]
private predicate source(Call call, TrackedField f, Field field, TCallableNode n) {
exists(Callable c, boolean fresh |
@@ -432,24 +446,28 @@ private module Cached {
)
}
overlay[global]
private predicate sink(Callable c, Field f, TCallableNode n) {
setsOwnField(c, f) and n = MkCallableNode(c, false)
or
setsOtherField(c, f) and n = MkCallableNode(c, _)
}
overlay[global]
private predicate prunedNode(TCallableNode n) {
sink(_, _, n)
or
exists(TCallableNode mid | edge(n, mid) and prunedNode(mid))
}
overlay[global]
private predicate prunedEdge(TCallableNode n1, TCallableNode n2) {
prunedNode(n1) and
prunedNode(n2) and
edge(n1, n2)
}
overlay[global]
private predicate edgePlus(TCallableNode c1, TCallableNode c2) = fastTC(prunedEdge/2)(c1, c2)
/**
@@ -457,6 +475,7 @@ private module Cached {
* where `f` and `call` share the same enclosing callable in which a
* `FieldRead` of `f` is reachable from `call`.
*/
overlay[global]
pragma[noopt]
private predicate updatesNamedFieldImpl(Call call, TrackedField f, Callable setter) {
exists(TCallableNode src, TCallableNode sink, Field field |
@@ -467,17 +486,23 @@ private module Cached {
}
bindingset[call, f]
overlay[global]
pragma[inline_late]
private predicate updatesNamedField0(Call call, TrackedField f, Callable setter) {
updatesNamedField(call, f, setter)
}
overlay[global]
cached
predicate defUpdatesNamedField(SsaImplicitUpdate def, TrackedField f, Callable setter) {
predicate defUpdatesNamedFieldImpl(SsaImplicitUpdate def, TrackedField f, Callable setter) {
f = def.getSourceVariable() and
updatesNamedField0(def.getCfgNode().asCall(), f, setter)
}
cached
predicate defUpdatesNamedField(SsaImplicitUpdate def, TrackedField f, Callable setter) =
forceLocal(defUpdatesNamedFieldImpl/3)(def, f, setter)
cached
predicate ssaUncertainImplicitUpdate(SsaImplicitUpdate def) {
exists(SsaSourceVariable v, BasicBlock bb, int i |
@@ -545,6 +570,7 @@ private module Cached {
}
cached
overlay[global]
module DataFlowIntegration {
import DataFlowIntegrationImpl
@@ -563,9 +589,9 @@ private module Cached {
cached // nothing is actually cached
module BarrierGuard<guardChecksSig/3 guardChecks> {
private predicate guardChecksAdjTypes(
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, Guards::GuardValue val
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
) {
guardChecks(g, e, val.asBooleanValue())
guardChecks(g, e, branch)
}
private Node getABarrierNodeImpl() {
@@ -657,18 +683,16 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
def instanceof SsaUncertainImplicitUpdate
}
class GuardValue = Guards::GuardValue;
class Guard = Guards::Guard;
/** Holds if the guard `guard` directly controls block `bb` upon evaluating to `val`. */
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, GuardValue val) {
guard.directlyValueControls(bb, val)
/** Holds if the guard `guard` directly controls block `bb` upon evaluating to `branch`. */
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
guard.directlyControls(bb, branch)
}
/** Holds if the guard `guard` controls block `bb` upon evaluating to `val`. */
predicate guardControlsBlock(Guard guard, BasicBlock bb, GuardValue val) {
guard.valueControls(bb, val)
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
guard.controls(bb, branch)
}
predicate includeWriteDefsInFlowStep() { none() }

View File

@@ -214,35 +214,24 @@ private predicate relevantNode(ObjNode n) {
exists(ObjNode mid | relevantNode(mid) and objStep(mid, n) and relevantNodeBack(n))
}
private newtype TObjFlowNode =
TObjNode(ObjNode n) { relevantNode(n) } or
TObjType(RefType t) { source(t, _) }
private predicate objStepPruned(TObjFlowNode node1, TObjFlowNode node2) {
exists(ObjNode n1, ObjNode n2 |
node1 = TObjNode(n1) and
node2 = TObjNode(n2) and
objStep(n1, n2)
)
or
exists(RefType t, ObjNode n |
node1 = TObjType(t) and
node2 = TObjNode(n) and
source(t, n)
)
pragma[noinline]
private predicate objStepPruned(ObjNode n1, ObjNode n2) {
objStep(n1, n2) and relevantNode(n1) and relevantNode(n2)
}
private predicate flowSrc(TObjFlowNode src) { src instanceof TObjType }
private predicate flowSink(TObjFlowNode sink) { exists(ObjNode n | sink = TObjNode(n) and sink(n)) }
private predicate stepPlus(TObjFlowNode n1, TObjFlowNode n2) =
doublyBoundedFastTC(objStepPruned/2, flowSrc/1, flowSink/1)(n1, n2)
private predicate stepPlus(Node n1, Node n2) = fastTC(objStepPruned/2)(n1, n2)
/**
* Holds if the qualifier `n` of an `Object.toString()` call might have type `t`.
*/
private predicate objType(ObjNode n, RefType t) { stepPlus(TObjType(t), TObjNode(n)) }
pragma[noopt]
private predicate objType(ObjNode n, RefType t) {
exists(ObjNode n2 |
sink(n) and
(stepPlus(n2, n) or n2 = n) and
source(t, n2)
)
}
private VirtualMethodCall objectToString(ObjNode n) {
result.getQualifier() = n.asExpr() and sink(n)

View File

@@ -2,7 +2,6 @@
* Provides predicates for reasoning about runtime call targets through virtual
* dispatch.
*/
overlay[local?]
module;
import java

View File

@@ -170,12 +170,15 @@ private module RegexFlow = DataFlow::Global<RegexFlowConfig>;
* As an optimisation, only regexes containing an infinite repitition quatifier (`+`, `*`, or `{x,}`)
* and therefore may be relevant for ReDoS queries are considered.
*/
predicate usedAsRegex(StringLiteral regex, string mode, boolean match_full_string) {
predicate usedAsRegexG(StringLiteral regex, string mode, boolean match_full_string) {
RegexFlow::flow(DataFlow::exprNode(regex), _) and
mode = "None" and // TODO: proper mode detection
mode = "None" and // TODO: proper mode detection
(if matchesFullString(regex) then match_full_string = true else match_full_string = false)
}
overlay[local]
predicate usedAsRegex(StringLiteral regex, string mode, boolean match_full_string) = forceLocal(usedAsRegexG/3)(regex, mode, match_full_string)
/**
* Holds if `regex` is used as a regular expression that is matched against a full string,
* as though it was implicitly surrounded by ^ and $.

View File

@@ -1,5 +1,5 @@
/** Provides a class hierarchy corresponding to a parse tree of regular expressions. */
overlay[local?]
overlay[local]
module;
private import semmle.code.java.regex.regex as RE // importing under a namescape to avoid naming conflict for `Top`.

View File

@@ -936,6 +936,7 @@ abstract class RegexString extends StringLiteral {
}
/** A string literal used as a regular expression */
overlay[local]
class Regex extends RegexString {
boolean matches_full_string;

View File

@@ -1,7 +1,3 @@
## 1.6.2
No user-facing changes.
## 1.6.1
### Minor Analysis Improvements

Some files were not shown because too many files have changed in this diff Show More