mirror of
https://github.com/github/codeql.git
synced 2026-05-27 09:31:30 +02:00
Compare commits
7 Commits
redsun82/a
...
alexet/glo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
652c048af5 | ||
|
|
eb31b1c0d3 | ||
|
|
979df35109 | ||
|
|
93e3702555 | ||
|
|
1f265efac8 | ||
|
|
8616943794 | ||
|
|
ee2de0170c |
7
.github/copilot-instructions.md
vendored
7
.github/copilot-instructions.md
vendored
@@ -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`
|
||||
|
||||
3
.github/workflows/build-ripunzip.yml
vendored
3
.github/workflows/build-ripunzip.yml
vendored
@@ -12,9 +12,6 @@ on:
|
||||
required: false
|
||||
default: openssl-3.5.0
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
## 0.4.14
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.13
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.4.14
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.14
|
||||
lastReleaseVersion: 0.4.13
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.15-dev
|
||||
version: 0.4.14-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
## 0.6.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.5
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.6.6
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.6
|
||||
lastReleaseVersion: 0.6.5
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
4
cpp/ql/lib/change-notes/2025-07-23-overrun-write.md
Normal file
4
cpp/ql/lib/change-notes/2025-07-23-overrun-write.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.
|
||||
@@ -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.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 5.4.0
|
||||
lastReleaseVersion: 5.3.0
|
||||
|
||||
@@ -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"]
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.4.5
|
||||
lastReleaseVersion: 1.4.4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.4.6-dev
|
||||
version: 1.4.5-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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. |
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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. |
|
||||
@@ -1 +0,0 @@
|
||||
Critical/InitialisationNotRun.ql
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
## 1.7.45
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.44
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.7.45
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.45
|
||||
lastReleaseVersion: 1.7.44
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.7.46-dev
|
||||
version: 1.7.45-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
## 1.7.45
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.44
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.7.45
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.45
|
||||
lastReleaseVersion: 1.7.44
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.7.46-dev
|
||||
version: 1.7.45-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
## 5.2.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 5.2.0
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 5.2.1
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 5.2.1
|
||||
lastReleaseVersion: 5.2.0
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
## 1.3.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.3.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.3.2
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.3.2
|
||||
lastReleaseVersion: 1.3.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-queries
|
||||
version: 1.3.3-dev
|
||||
version: 1.3.2-dev
|
||||
groups:
|
||||
- csharp
|
||||
- queries
|
||||
|
||||
@@ -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``"
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
## 1.0.28
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.0.27
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.0.28
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.0.28
|
||||
lastReleaseVersion: 1.0.27
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql-go-consistency-queries
|
||||
version: 1.0.29-dev
|
||||
version: 1.0.28-dev
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
## 4.3.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 4.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 4.3.1
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 4.3.1
|
||||
lastReleaseVersion: 4.3.0
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
## 1.4.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.4.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.4.2
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.4.2
|
||||
lastReleaseVersion: 1.4.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-queries
|
||||
version: 1.4.3-dev
|
||||
version: 1.4.2-dev
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
@@ -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
|
||||
|
||||
BIN
java/kotlin-extractor/deps/kotlin-compiler-2.2.20-Beta2.jar
(Stored with Git LFS)
BIN
java/kotlin-extractor/deps/kotlin-compiler-2.2.20-Beta2.jar
(Stored with Git LFS)
Binary file not shown.
BIN
java/kotlin-extractor/deps/kotlin-compiler-embeddable-2.2.20-Beta2.jar
(Stored with Git LFS)
BIN
java/kotlin-extractor/deps/kotlin-compiler-embeddable-2.2.20-Beta2.jar
(Stored with Git LFS)
Binary file not shown.
BIN
java/kotlin-extractor/deps/kotlin-stdlib-2.2.20-Beta2.jar
(Stored with Git LFS)
BIN
java/kotlin-extractor/deps/kotlin-stdlib-2.2.20-Beta2.jar
(Stored with Git LFS)
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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`.
|
||||
@@ -1,5 +0,0 @@
|
||||
## 7.5.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Kotlin versions up to 2.2.2\ *x* are now supported.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 7.5.0
|
||||
lastReleaseVersion: 7.4.0
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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>;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
/**
|
||||
|
||||
@@ -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() }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* Provides predicates for reasoning about runtime call targets through virtual
|
||||
* dispatch.
|
||||
*/
|
||||
overlay[local?]
|
||||
module;
|
||||
|
||||
import java
|
||||
|
||||
@@ -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 $.
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user