Merge remote-tracking branch 'origin/main' into smowton/admin/merge-rc317-into-main

This commit is contained in:
Chris Smowton
2025-03-19 16:01:29 +00:00
2476 changed files with 45571 additions and 29067 deletions

View File

@@ -1,19 +1,3 @@
import codeql.ruby.dataflow.SSA
import codeql.ruby.dataflow.internal.SsaImpl
import Consistency
class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
class MyRelevantDefinitionExt extends RelevantDefinitionExt, DefinitionExt {
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}

View File

@@ -74,10 +74,10 @@ CfgNodes::ExprCfgNode getAPostUpdateNodeForArg(Argument arg) {
/** Gets the SSA definition node corresponding to parameter `p`. */
pragma[nomagic]
SsaImpl::DefinitionExt getParameterDef(NamedParameter p) {
Ssa::Definition getParameterDef(NamedParameter p) {
exists(BasicBlock bb, int i |
bb.getNode(i).getAstNode() = p.getDefiningAccess() and
result.definesAt(_, bb, i, _)
result.definesAt(_, bb, i)
)
}
@@ -111,12 +111,14 @@ module SsaFlow {
n = toParameterNode(result.(Impl::ParameterNode).getParameter())
}
predicate localFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
Impl::localFlowStep(def, asNode(nodeFrom), asNode(nodeTo), isUseStep)
predicate localFlowStep(
SsaImpl::SsaInput::SourceVariable v, Node nodeFrom, Node nodeTo, boolean isUseStep
) {
Impl::localFlowStep(v, asNode(nodeFrom), asNode(nodeTo), isUseStep)
}
predicate localMustFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
Impl::localMustFlowStep(def, asNode(nodeFrom), asNode(nodeTo))
predicate localMustFlowStep(Node nodeFrom, Node nodeTo) {
Impl::localMustFlowStep(_, asNode(nodeFrom), asNode(nodeTo))
}
}
@@ -175,7 +177,7 @@ module LocalFlow {
}
predicate localMustFlowStep(Node node1, Node node2) {
SsaFlow::localMustFlowStep(_, node1, node2)
SsaFlow::localMustFlowStep(node1, node2)
or
node1.asExpr() = node2.asExpr().(CfgNodes::ExprNodes::AssignExprCfgNode).getRhs()
or
@@ -386,15 +388,15 @@ module VariableCapture {
Flow::clearsContent(asClosureNode(node), c.getVariable())
}
class CapturedSsaDefinitionExt extends SsaImpl::DefinitionExt {
CapturedSsaDefinitionExt() { this.getSourceVariable() instanceof CapturedVariable }
class CapturedSsaDefinition extends SsaImpl::Definition {
CapturedSsaDefinition() { this.getSourceVariable() instanceof CapturedVariable }
}
// From an assignment or implicit initialization of a captured variable to its flow-insensitive node
private predicate flowInsensitiveWriteStep(
SsaDefinitionNodeImpl node1, CapturedVariableNode node2, CapturedVariable v
) {
exists(CapturedSsaDefinitionExt def |
exists(CapturedSsaDefinition def |
def = node1.getDefinition() and
def.getSourceVariable() = v and
(
@@ -410,7 +412,7 @@ module VariableCapture {
private predicate flowInsensitiveReadStep(
CapturedVariableNode node1, SsaDefinitionNodeImpl node2, CapturedVariable v
) {
exists(CapturedSsaDefinitionExt def |
exists(CapturedSsaDefinition def |
node1.getVariable() = v and
def = node2.getDefinition() and
def.getSourceVariable() = v and
@@ -525,10 +527,10 @@ private module Cached {
(
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
or
exists(SsaImpl::DefinitionExt def, boolean isUseStep |
SsaFlow::localFlowStep(def, nodeFrom, nodeTo, isUseStep) and
exists(SsaImpl::SsaInput::SourceVariable v, boolean isUseStep |
SsaFlow::localFlowStep(v, nodeFrom, nodeTo, isUseStep) and
// captured variables are handled by the shared `VariableCapture` library
not def instanceof VariableCapture::CapturedSsaDefinitionExt
not v instanceof VariableCapture::CapturedVariable
|
isUseStep = false
or
@@ -770,7 +772,7 @@ class SsaNode extends NodeImpl, TSsaNode {
class SsaDefinitionNodeImpl extends SsaNode {
override SsaImpl::DataFlowIntegration::SsaDefinitionNode node;
SsaImpl::Definition getDefinition() { result = node.getDefinition() }
Ssa::Definition getDefinition() { result = node.getDefinition() }
override predicate isHidden() {
exists(SsaImpl::Definition def | def = this.getDefinition() |
@@ -2476,7 +2478,7 @@ module TypeInference {
n = def or
n.asExpr() =
any(CfgNodes::ExprCfgNode read |
read = def.getDefinition().(SsaImpl::DefinitionExt).getARead() and
read = def.getDefinition().getARead() and
not isTypeCheckedRead(read, _) // could in principle be checked against a new type
)
)

View File

@@ -75,12 +75,6 @@ class PhiNode = Impl::PhiNode;
module Consistency = Impl::Consistency;
module ExposedForTestingOnly {
predicate ssaDefReachesReadExt = Impl::ssaDefReachesReadExt/4;
predicate phiHasInputFromBlockExt = Impl::phiHasInputFromBlockExt/3;
}
/** Holds if `v` is uninitialized at index `i` in entry block `bb`. */
predicate uninitializedWrite(Cfg::EntryBasicBlock bb, int i, LocalVariable v) {
v.getDeclaringScope() = bb.getScope() and
@@ -224,7 +218,7 @@ private predicate hasVariableReadWithCapturedWrite(
pragma[noinline]
deprecated private predicate adjacentDefReadExt(
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2,
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2,
SsaInput::SourceVariable v
) {
Impl::adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and
@@ -232,10 +226,10 @@ deprecated private predicate adjacentDefReadExt(
}
deprecated private predicate adjacentDefReachesReadExt(
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
) {
exists(SsaInput::SourceVariable v | adjacentDefReadExt(def, bb1, i1, bb2, i2, v) |
def.definesAt(v, bb1, i1, _)
def.definesAt(v, bb1, i1)
or
SsaInput::variableRead(bb1, i1, v, true)
)
@@ -248,7 +242,7 @@ deprecated private predicate adjacentDefReachesReadExt(
}
deprecated private predicate adjacentDefReachesUncertainReadExt(
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
) {
adjacentDefReachesReadExt(def, bb1, i1, bb2, i2) and
SsaInput::variableRead(bb2, i2, _, false)
@@ -257,7 +251,7 @@ deprecated private predicate adjacentDefReachesUncertainReadExt(
/** Same as `lastRefRedef`, but skips uncertain reads. */
pragma[nomagic]
deprecated private predicate lastRefSkipUncertainReadsExt(
DefinitionExt def, SsaInput::BasicBlock bb, int i
Definition def, SsaInput::BasicBlock bb, int i
) {
Impl::lastRef(def, bb, i) and
not SsaInput::variableRead(bb, i, def.getSourceVariable(), false)
@@ -387,13 +381,15 @@ private module Cached {
import DataFlowIntegrationImpl
cached
predicate localFlowStep(DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
DataFlowIntegrationImpl::localFlowStep(def, nodeFrom, nodeTo, isUseStep)
predicate localFlowStep(
SsaInput::SourceVariable v, Node nodeFrom, Node nodeTo, boolean isUseStep
) {
DataFlowIntegrationImpl::localFlowStep(v, nodeFrom, nodeTo, isUseStep)
}
cached
predicate localMustFlowStep(DefinitionExt def, Node nodeFrom, Node nodeTo) {
DataFlowIntegrationImpl::localMustFlowStep(def, nodeFrom, nodeTo)
predicate localMustFlowStep(SsaInput::SourceVariable v, Node nodeFrom, Node nodeTo) {
DataFlowIntegrationImpl::localMustFlowStep(v, nodeFrom, nodeTo)
}
signature predicate guardChecksSig(Cfg::CfgNodes::AstCfgNode g, Cfg::CfgNode e, boolean branch);
@@ -417,33 +413,6 @@ private module Cached {
import Cached
/**
* An extended static single assignment (SSA) definition.
*
* This is either a normal SSA definition (`Definition`) or a
* phi-read node (`PhiReadNode`).
*
* Only intended for internal use.
*/
class DefinitionExt extends Impl::DefinitionExt {
VariableReadAccessCfgNode getARead() { result = getARead(this) }
override string toString() { result = this.(Ssa::Definition).toString() }
override Location getLocation() { result = this.(Ssa::Definition).getLocation() }
}
/**
* A phi-read node.
*
* Only intended for internal use.
*/
class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
override string toString() { result = "SSA phi read(" + this.getSourceVariable() + ")" }
override Location getLocation() { result = Impl::PhiReadNode.super.getLocation() }
}
class NormalParameter extends Parameter {
NormalParameter() {
this instanceof SimpleParameter or
@@ -457,10 +426,10 @@ class NormalParameter extends Parameter {
/** Gets the SSA definition node corresponding to parameter `p`. */
pragma[nomagic]
DefinitionExt getParameterDef(NamedParameter p) {
Definition getParameterDef(NamedParameter p) {
exists(Cfg::BasicBlock bb, int i |
bb.getNode(i).getAstNode() = p.getDefiningAccess() and
result.definesAt(_, bb, i, _)
result.definesAt(_, bb, i)
)
}
@@ -519,21 +488,24 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { p.isInitializedBy(def) }
class Guard extends Cfg::CfgNodes::AstCfgNode {
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
/**
* Holds if the control flow branching from `bb1` is dependent on this guard,
* and that the edge from `bb1` to `bb2` corresponds to the evaluation of this
* guard to `branch`.
*/
predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
exists(Cfg::SuccessorTypes::ConditionalSuccessor s |
this.getBasicBlock() = bb1 and
bb2 = bb1.getASuccessor(s) and
s.getValue() = branch
)
}
}
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
Guards::guardControlsBlock(guard, bb, branch)
}
/** Gets an immediate conditional successor of basic block `bb`, if any. */
SsaInput::BasicBlock getAConditionalBasicBlockSuccessor(SsaInput::BasicBlock bb, boolean branch) {
exists(Cfg::SuccessorTypes::ConditionalSuccessor s |
result = bb.getASuccessor(s) and
s.getValue() = branch
)
}
}
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;

View File

@@ -12,7 +12,6 @@ newStyleBarrierGuards
| barrier-guards.rb:28:5:28:7 | foo |
| barrier-guards.rb:37:21:38:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:38:5:38:7 | foo |
| barrier-guards.rb:43:16:46:5 | [input] SSA phi read(foo) |
| barrier-guards.rb:45:9:45:11 | foo |
| barrier-guards.rb:70:22:71:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:71:5:71:7 | foo |
@@ -51,9 +50,7 @@ newStyleBarrierGuards
| barrier-guards.rb:199:4:199:15 | [input] SSA phi read(foo) |
| barrier-guards.rb:199:4:199:31 | [input] SSA phi read(foo) |
| barrier-guards.rb:199:20:199:31 | [input] SSA phi read(foo) |
| barrier-guards.rb:203:4:203:15 | [input] SSA phi read(foo) |
| barrier-guards.rb:203:36:203:47 | [input] SSA phi read(foo) |
| barrier-guards.rb:207:21:207:21 | [input] SSA phi read(foo) |
| barrier-guards.rb:207:22:208:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:208:5:208:7 | foo |
| barrier-guards.rb:211:22:212:19 | [input] SSA phi read(foo) |
@@ -64,8 +61,6 @@ newStyleBarrierGuards
| barrier-guards.rb:219:21:219:32 | [input] SSA phi read(foo) |
| barrier-guards.rb:219:95:220:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:220:5:220:7 | foo |
| barrier-guards.rb:227:21:227:21 | [input] SSA phi read(foo) |
| barrier-guards.rb:227:22:228:7 | [input] SSA phi read(foo) |
| barrier-guards.rb:232:18:233:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:233:5:233:7 | foo |
| barrier-guards.rb:237:19:237:38 | [input] SSA phi read(foo) |

View File

@@ -25,12 +25,13 @@ models
| 24 | Summary: any; Method[matchedByName]; Argument[0]; ReturnValue; taint |
| 25 | Summary: any; Method[readElementOne]; Argument[self].Element[1]; ReturnValue; value |
| 26 | Summary: any; Method[readExactlyElementOne]; Argument[self].Element[1!]; ReturnValue; value |
| 27 | Summary: any; Method[set_value]; Argument[0]; Argument[self].Field[@value]; value |
| 28 | Summary: any; Method[withElementOne]; Argument[self].WithElement[1]; ReturnValue; value |
| 29 | Summary: any; Method[withExactlyElementOne]; Argument[self].WithElement[1!]; ReturnValue; value |
| 30 | Summary: any; Method[withoutElementOneAndTwo]; Argument[self].WithoutElement[1].WithoutElement[2].WithElement[any]; Argument[self]; value |
| 31 | Summary: any; Method[withoutElementOne]; Argument[self].WithoutElement[1]; Argument[self]; value |
| 32 | Summary: any; Method[withoutExactlyElementOne]; Argument[self].WithoutElement[1!]; Argument[self]; value |
| 27 | Summary: any; Method[saveToDatabase]; Argument[self]; SyntheticGlobal[db]; value |
| 28 | Summary: any; Method[set_value]; Argument[0]; Argument[self].Field[@value]; value |
| 29 | Summary: any; Method[withElementOne]; Argument[self].WithElement[1]; ReturnValue; value |
| 30 | Summary: any; Method[withExactlyElementOne]; Argument[self].WithElement[1!]; ReturnValue; value |
| 31 | Summary: any; Method[withoutElementOneAndTwo]; Argument[self].WithoutElement[1].WithoutElement[2].WithElement[any]; Argument[self]; value |
| 32 | Summary: any; Method[withoutElementOne]; Argument[self].WithoutElement[1]; Argument[self]; value |
| 33 | Summary: any; Method[withoutExactlyElementOne]; Argument[self].WithoutElement[1!]; Argument[self]; value |
edges
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:2:6:2:12 | tainted | provenance | |
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:2:6:2:12 | tainted | provenance | |
@@ -201,10 +202,10 @@ edges
| summaries.rb:87:1:87:1 | b : [collection] [element] | summaries.rb:89:6:89:6 | b : [collection] [element] | provenance | |
| summaries.rb:87:1:87:1 | b : [collection] [element] | summaries.rb:90:6:90:6 | b : [collection] [element] | provenance | |
| summaries.rb:87:1:87:1 | b : [collection] [element] | summaries.rb:90:6:90:6 | b : [collection] [element] | provenance | |
| summaries.rb:87:5:87:5 | a : Array [element 1] | summaries.rb:87:5:87:22 | call to withElementOne : Array [element 1] | provenance | MaD:28 |
| summaries.rb:87:5:87:5 | a : Array [element 1] | summaries.rb:87:5:87:22 | call to withElementOne : Array [element 1] | provenance | MaD:28 |
| summaries.rb:87:5:87:5 | a : [collection] [element] | summaries.rb:87:5:87:22 | call to withElementOne : [collection] [element] | provenance | MaD:28 |
| summaries.rb:87:5:87:5 | a : [collection] [element] | summaries.rb:87:5:87:22 | call to withElementOne : [collection] [element] | provenance | MaD:28 |
| summaries.rb:87:5:87:5 | a : Array [element 1] | summaries.rb:87:5:87:22 | call to withElementOne : Array [element 1] | provenance | MaD:29 |
| summaries.rb:87:5:87:5 | a : Array [element 1] | summaries.rb:87:5:87:22 | call to withElementOne : Array [element 1] | provenance | MaD:29 |
| summaries.rb:87:5:87:5 | a : [collection] [element] | summaries.rb:87:5:87:22 | call to withElementOne : [collection] [element] | provenance | MaD:29 |
| summaries.rb:87:5:87:5 | a : [collection] [element] | summaries.rb:87:5:87:22 | call to withElementOne : [collection] [element] | provenance | MaD:29 |
| summaries.rb:87:5:87:22 | call to withElementOne : Array [element 1] | summaries.rb:87:1:87:1 | b : Array [element 1] | provenance | |
| summaries.rb:87:5:87:22 | call to withElementOne : Array [element 1] | summaries.rb:87:1:87:1 | b : Array [element 1] | provenance | |
| summaries.rb:87:5:87:22 | call to withElementOne : [collection] [element] | summaries.rb:87:1:87:1 | b : [collection] [element] | provenance | |
@@ -219,8 +220,8 @@ edges
| summaries.rb:90:6:90:6 | b : [collection] [element] | summaries.rb:90:6:90:9 | ...[...] | provenance | |
| summaries.rb:91:1:91:1 | c : Array [element 1] | summaries.rb:93:6:93:6 | c : Array [element 1] | provenance | |
| summaries.rb:91:1:91:1 | c : Array [element 1] | summaries.rb:93:6:93:6 | c : Array [element 1] | provenance | |
| summaries.rb:91:5:91:5 | a : Array [element 1] | summaries.rb:91:5:91:29 | call to withExactlyElementOne : Array [element 1] | provenance | MaD:29 |
| summaries.rb:91:5:91:5 | a : Array [element 1] | summaries.rb:91:5:91:29 | call to withExactlyElementOne : Array [element 1] | provenance | MaD:29 |
| summaries.rb:91:5:91:5 | a : Array [element 1] | summaries.rb:91:5:91:29 | call to withExactlyElementOne : Array [element 1] | provenance | MaD:30 |
| summaries.rb:91:5:91:5 | a : Array [element 1] | summaries.rb:91:5:91:29 | call to withExactlyElementOne : Array [element 1] | provenance | MaD:30 |
| summaries.rb:91:5:91:29 | call to withExactlyElementOne : Array [element 1] | summaries.rb:91:1:91:1 | c : Array [element 1] | provenance | |
| summaries.rb:91:5:91:29 | call to withExactlyElementOne : Array [element 1] | summaries.rb:91:1:91:1 | c : Array [element 1] | provenance | |
| summaries.rb:93:6:93:6 | c : Array [element 1] | summaries.rb:93:6:93:9 | ...[...] | provenance | |
@@ -235,10 +236,10 @@ edges
| summaries.rb:95:1:95:1 | [post] a : [collection] [element] | summaries.rb:97:6:97:6 | a : [collection] [element] | provenance | |
| summaries.rb:95:1:95:1 | [post] a : [collection] [element] | summaries.rb:98:6:98:6 | a : [collection] [element] | provenance | |
| summaries.rb:95:1:95:1 | [post] a : [collection] [element] | summaries.rb:98:6:98:6 | a : [collection] [element] | provenance | |
| summaries.rb:95:1:95:1 | a : Array [element 2] | summaries.rb:95:1:95:1 | [post] a : Array [element 2] | provenance | MaD:32 |
| summaries.rb:95:1:95:1 | a : Array [element 2] | summaries.rb:95:1:95:1 | [post] a : Array [element 2] | provenance | MaD:32 |
| summaries.rb:95:1:95:1 | a : [collection] [element] | summaries.rb:95:1:95:1 | [post] a : [collection] [element] | provenance | MaD:32 |
| summaries.rb:95:1:95:1 | a : [collection] [element] | summaries.rb:95:1:95:1 | [post] a : [collection] [element] | provenance | MaD:32 |
| summaries.rb:95:1:95:1 | a : Array [element 2] | summaries.rb:95:1:95:1 | [post] a : Array [element 2] | provenance | MaD:33 |
| summaries.rb:95:1:95:1 | a : Array [element 2] | summaries.rb:95:1:95:1 | [post] a : Array [element 2] | provenance | MaD:33 |
| summaries.rb:95:1:95:1 | a : [collection] [element] | summaries.rb:95:1:95:1 | [post] a : [collection] [element] | provenance | MaD:33 |
| summaries.rb:95:1:95:1 | a : [collection] [element] | summaries.rb:95:1:95:1 | [post] a : [collection] [element] | provenance | MaD:33 |
| summaries.rb:96:6:96:6 | a : [collection] [element] | summaries.rb:96:6:96:9 | ...[...] | provenance | |
| summaries.rb:96:6:96:6 | a : [collection] [element] | summaries.rb:96:6:96:9 | ...[...] | provenance | |
| summaries.rb:97:6:97:6 | a : [collection] [element] | summaries.rb:97:6:97:9 | ...[...] | provenance | |
@@ -249,8 +250,8 @@ edges
| summaries.rb:98:6:98:6 | a : [collection] [element] | summaries.rb:98:6:98:9 | ...[...] | provenance | |
| summaries.rb:99:1:99:1 | [post] a : Array [element 2] | summaries.rb:102:6:102:6 | a : Array [element 2] | provenance | |
| summaries.rb:99:1:99:1 | [post] a : Array [element 2] | summaries.rb:102:6:102:6 | a : Array [element 2] | provenance | |
| summaries.rb:99:1:99:1 | a : Array [element 2] | summaries.rb:99:1:99:1 | [post] a : Array [element 2] | provenance | MaD:31 |
| summaries.rb:99:1:99:1 | a : Array [element 2] | summaries.rb:99:1:99:1 | [post] a : Array [element 2] | provenance | MaD:31 |
| summaries.rb:99:1:99:1 | a : Array [element 2] | summaries.rb:99:1:99:1 | [post] a : Array [element 2] | provenance | MaD:32 |
| summaries.rb:99:1:99:1 | a : Array [element 2] | summaries.rb:99:1:99:1 | [post] a : Array [element 2] | provenance | MaD:32 |
| summaries.rb:102:6:102:6 | a : Array [element 2] | summaries.rb:102:6:102:9 | ...[...] | provenance | |
| summaries.rb:102:6:102:6 | a : Array [element 2] | summaries.rb:102:6:102:9 | ...[...] | provenance | |
| summaries.rb:103:1:103:1 | [post] d : [collection] [element 3] | summaries.rb:104:1:104:1 | d : [collection] [element 3] | provenance | |
@@ -259,14 +260,14 @@ edges
| summaries.rb:103:8:103:22 | call to source | summaries.rb:103:1:103:1 | [post] d : [collection] [element 3] | provenance | |
| summaries.rb:104:1:104:1 | [post] d : [collection] [element 3] | summaries.rb:108:6:108:6 | d : [collection] [element 3] | provenance | |
| summaries.rb:104:1:104:1 | [post] d : [collection] [element 3] | summaries.rb:108:6:108:6 | d : [collection] [element 3] | provenance | |
| summaries.rb:104:1:104:1 | d : [collection] [element 3] | summaries.rb:104:1:104:1 | [post] d : [collection] [element 3] | provenance | MaD:30 |
| summaries.rb:104:1:104:1 | d : [collection] [element 3] | summaries.rb:104:1:104:1 | [post] d : [collection] [element 3] | provenance | MaD:30 |
| summaries.rb:104:1:104:1 | d : [collection] [element 3] | summaries.rb:104:1:104:1 | [post] d : [collection] [element 3] | provenance | MaD:31 |
| summaries.rb:104:1:104:1 | d : [collection] [element 3] | summaries.rb:104:1:104:1 | [post] d : [collection] [element 3] | provenance | MaD:31 |
| summaries.rb:108:6:108:6 | d : [collection] [element 3] | summaries.rb:108:6:108:9 | ...[...] | provenance | |
| summaries.rb:108:6:108:6 | d : [collection] [element 3] | summaries.rb:108:6:108:9 | ...[...] | provenance | |
| summaries.rb:111:1:111:1 | [post] x [@value] | summaries.rb:112:6:112:6 | x [@value] | provenance | |
| summaries.rb:111:1:111:1 | [post] x [@value] | summaries.rb:112:6:112:6 | x [@value] | provenance | |
| summaries.rb:111:13:111:26 | call to source | summaries.rb:111:1:111:1 | [post] x [@value] | provenance | MaD:27 |
| summaries.rb:111:13:111:26 | call to source | summaries.rb:111:1:111:1 | [post] x [@value] | provenance | MaD:27 |
| summaries.rb:111:13:111:26 | call to source | summaries.rb:111:1:111:1 | [post] x [@value] | provenance | MaD:28 |
| summaries.rb:111:13:111:26 | call to source | summaries.rb:111:1:111:1 | [post] x [@value] | provenance | MaD:28 |
| summaries.rb:112:6:112:6 | x [@value] | summaries.rb:112:6:112:16 | call to get_value | provenance | MaD:22 |
| summaries.rb:112:6:112:6 | x [@value] | summaries.rb:112:6:112:16 | call to get_value | provenance | MaD:22 |
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:128:14:128:20 | tainted | provenance | |
@@ -294,6 +295,24 @@ edges
| summaries.rb:131:16:131:22 | tainted | summaries.rb:131:1:131:23 | synthetic splat argument | provenance | Sink:MaD:4 |
| summaries.rb:157:14:160:3 | do ... end : [lambda] [captured tainted] | summaries.rb:158:15:158:21 | tainted | provenance | heuristic-callback Sink:MaD:6 |
| summaries.rb:157:14:160:3 | do ... end : [lambda] [captured tainted] | summaries.rb:158:15:158:21 | tainted | provenance | heuristic-callback Sink:MaD:6 |
| summaries.rb:172:5:172:6 | [post] @x [@someField] | summaries.rb:172:5:172:6 | [post] self : SynthGlobalTest [@x, @someField] | provenance | |
| summaries.rb:172:5:172:6 | [post] @x [@someField] | summaries.rb:172:5:172:6 | [post] self : SynthGlobalTest [@x, @someField] | provenance | |
| summaries.rb:172:5:172:6 | [post] self : SynthGlobalTest [@x, @someField] | summaries.rb:173:5:173:6 | self : SynthGlobalTest [@x, @someField] | provenance | |
| summaries.rb:172:5:172:6 | [post] self : SynthGlobalTest [@x, @someField] | summaries.rb:173:5:173:6 | self : SynthGlobalTest [@x, @someField] | provenance | |
| summaries.rb:172:20:172:36 | call to source | summaries.rb:172:5:172:6 | [post] @x [@someField] | provenance | |
| summaries.rb:172:20:172:36 | call to source | summaries.rb:172:5:172:6 | [post] @x [@someField] | provenance | |
| summaries.rb:173:5:173:6 | @x [@someField] | summaries.rb:177:10:177:27 | call to readFromDatabase [@someField] | provenance | MaD:27 |
| summaries.rb:173:5:173:6 | @x [@someField] | summaries.rb:177:10:177:27 | call to readFromDatabase [@someField] | provenance | MaD:27 |
| summaries.rb:173:5:173:6 | self : SynthGlobalTest [@x, @someField] | summaries.rb:173:5:173:6 | @x [@someField] | provenance | |
| summaries.rb:173:5:173:6 | self : SynthGlobalTest [@x, @someField] | summaries.rb:173:5:173:6 | @x [@someField] | provenance | |
| summaries.rb:177:5:177:6 | [post] self [@x, @someField] | summaries.rb:179:10:179:11 | self [@x, @someField] | provenance | |
| summaries.rb:177:5:177:6 | [post] self [@x, @someField] | summaries.rb:179:10:179:11 | self [@x, @someField] | provenance | |
| summaries.rb:177:10:177:27 | call to readFromDatabase [@someField] | summaries.rb:177:5:177:6 | [post] self [@x, @someField] | provenance | |
| summaries.rb:177:10:177:27 | call to readFromDatabase [@someField] | summaries.rb:177:5:177:6 | [post] self [@x, @someField] | provenance | |
| summaries.rb:179:10:179:11 | @x [@someField] | summaries.rb:179:10:179:21 | call to someField | provenance | |
| summaries.rb:179:10:179:11 | @x [@someField] | summaries.rb:179:10:179:21 | call to someField | provenance | |
| summaries.rb:179:10:179:11 | self [@x, @someField] | summaries.rb:179:10:179:11 | @x [@someField] | provenance | |
| summaries.rb:179:10:179:11 | self [@x, @someField] | summaries.rb:179:10:179:11 | @x [@someField] | provenance | |
nodes
| summaries.rb:1:11:1:36 | call to identity | semmle.label | call to identity |
| summaries.rb:1:11:1:36 | call to identity | semmle.label | call to identity |
@@ -553,6 +572,26 @@ nodes
| summaries.rb:163:20:163:36 | call to source | semmle.label | call to source |
| summaries.rb:166:20:166:36 | call to source | semmle.label | call to source |
| summaries.rb:166:20:166:36 | call to source | semmle.label | call to source |
| summaries.rb:172:5:172:6 | [post] @x [@someField] | semmle.label | [post] @x [@someField] |
| summaries.rb:172:5:172:6 | [post] @x [@someField] | semmle.label | [post] @x [@someField] |
| summaries.rb:172:5:172:6 | [post] self : SynthGlobalTest [@x, @someField] | semmle.label | [post] self : SynthGlobalTest [@x, @someField] |
| summaries.rb:172:5:172:6 | [post] self : SynthGlobalTest [@x, @someField] | semmle.label | [post] self : SynthGlobalTest [@x, @someField] |
| summaries.rb:172:20:172:36 | call to source | semmle.label | call to source |
| summaries.rb:172:20:172:36 | call to source | semmle.label | call to source |
| summaries.rb:173:5:173:6 | @x [@someField] | semmle.label | @x [@someField] |
| summaries.rb:173:5:173:6 | @x [@someField] | semmle.label | @x [@someField] |
| summaries.rb:173:5:173:6 | self : SynthGlobalTest [@x, @someField] | semmle.label | self : SynthGlobalTest [@x, @someField] |
| summaries.rb:173:5:173:6 | self : SynthGlobalTest [@x, @someField] | semmle.label | self : SynthGlobalTest [@x, @someField] |
| summaries.rb:177:5:177:6 | [post] self [@x, @someField] | semmle.label | [post] self [@x, @someField] |
| summaries.rb:177:5:177:6 | [post] self [@x, @someField] | semmle.label | [post] self [@x, @someField] |
| summaries.rb:177:10:177:27 | call to readFromDatabase [@someField] | semmle.label | call to readFromDatabase [@someField] |
| summaries.rb:177:10:177:27 | call to readFromDatabase [@someField] | semmle.label | call to readFromDatabase [@someField] |
| summaries.rb:179:10:179:11 | @x [@someField] | semmle.label | @x [@someField] |
| summaries.rb:179:10:179:11 | @x [@someField] | semmle.label | @x [@someField] |
| summaries.rb:179:10:179:11 | self [@x, @someField] | semmle.label | self [@x, @someField] |
| summaries.rb:179:10:179:11 | self [@x, @someField] | semmle.label | self [@x, @someField] |
| summaries.rb:179:10:179:21 | call to someField | semmle.label | call to someField |
| summaries.rb:179:10:179:21 | call to someField | semmle.label | call to someField |
subpaths
| summaries.rb:4:24:4:30 | tainted | summaries.rb:4:36:4:36 | x | summaries.rb:6:3:6:3 | x | summaries.rb:4:12:7:3 | call to apply_block |
| summaries.rb:4:24:4:30 | tainted | summaries.rb:4:36:4:36 | x | summaries.rb:6:3:6:3 | x | summaries.rb:4:12:7:3 | call to apply_block |
@@ -670,4 +709,6 @@ invalidSpecComponent
| summaries.rb:163:20:163:36 | call to source | summaries.rb:163:20:163:36 | call to source | summaries.rb:163:20:163:36 | call to source | $@ | summaries.rb:163:20:163:36 | call to source | call to source |
| summaries.rb:166:20:166:36 | call to source | summaries.rb:166:20:166:36 | call to source | summaries.rb:166:20:166:36 | call to source | $@ | summaries.rb:166:20:166:36 | call to source | call to source |
| summaries.rb:166:20:166:36 | call to source | summaries.rb:166:20:166:36 | call to source | summaries.rb:166:20:166:36 | call to source | $@ | summaries.rb:166:20:166:36 | call to source | call to source |
| summaries.rb:179:10:179:21 | call to someField | summaries.rb:172:20:172:36 | call to source | summaries.rb:179:10:179:21 | call to someField | $@ | summaries.rb:172:20:172:36 | call to source | call to source |
| summaries.rb:179:10:179:21 | call to someField | summaries.rb:172:20:172:36 | call to source | summaries.rb:179:10:179:21 | call to someField | $@ | summaries.rb:172:20:172:36 | call to source | call to source |
warning

View File

@@ -41,6 +41,8 @@ extensions:
- ['any', 'Method[withoutElementOneAndTwo]', 'Argument[self].WithoutElement[1].WithoutElement[2].WithElement[any]', 'Argument[self]', 'value']
- ['any', 'Method[withoutElementOne]', 'Argument[self].WithoutElement[1]', 'Argument[self]', 'value']
- ['any', 'Method[withoutExactlyElementOne]', 'Argument[self].WithoutElement[1!]', 'Argument[self]', 'value']
- ['any', 'Method[saveToDatabase]', 'Argument[self]', 'SyntheticGlobal[db]', 'value']
- ['any', 'Method[readFromDatabase]', 'SyntheticGlobal[db]', 'ReturnValue', 'value']
- addsTo:
pack: codeql/ruby-all

View File

@@ -166,3 +166,17 @@ class FuzzySub < FuzzyLib::Foo
self.fuzzyCall(source("tainted")) # $ hasValueFlow=tainted
end
end
class SynthGlobalTest
def store
@x.someField = source("tainted")
@x.saveToDatabase()
end
def read
@x = readFromDatabase()
sink(@x)
sink(@x.someField) # $ hasValueFlow=tainted
sink(@x.someOtherField)
end
end

View File

@@ -597,7 +597,7 @@ phiReadNode
| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:3 | x |
| ssa.rb:94:3:95:10 | SSA phi read(self) | ssa.rb:90:1:103:3 | self |
| ssa.rb:94:3:95:10 | SSA phi read(x) | ssa.rb:91:3:91:3 | x |
phiReadNodeRead
phiReadNodeFirstRead
| parameters.rb:26:3:26:11 | SSA phi read(name) | parameters.rb:25:15:25:18 | name | parameters.rb:26:8:26:11 | name |
| ssa.rb:5:3:13:5 | SSA phi read(self) | ssa.rb:1:1:16:3 | self | ssa.rb:15:3:15:8 | self |
| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self |
@@ -607,12 +607,16 @@ phiReadNodeRead
| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:3 | x | ssa.rb:101:10:101:10 | x |
phiReadInput
| parameters.rb:26:3:26:11 | SSA phi read(name) | parameters.rb:25:15:25:18 | name |
| ssa.rb:5:3:13:5 | SSA phi read(self) | ssa.rb:1:1:16:3 | self (m) |
| parameters.rb:26:3:26:11 | SSA phi read(name) | parameters.rb:25:40:25:43 | SSA read(name) |
| ssa.rb:5:3:13:5 | SSA phi read(self) | ssa.rb:8:5:8:14 | SSA read(self) |
| ssa.rb:5:3:13:5 | SSA phi read(self) | ssa.rb:12:5:12:14 | SSA read(self) |
| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:18:1:23:3 | self (m1) |
| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:19:9:19:9 | SSA phi read(self) |
| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:90:1:103:3 | self (m12) |
| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:20:5:20:10 | SSA read(self) |
| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:93:5:93:10 | SSA read(self) |
| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:94:3:95:10 | SSA phi read(self) |
| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:3 | x |
| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:93:10:93:10 | SSA read(x) |
| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:94:3:95:10 | SSA phi read(x) |
| ssa.rb:94:3:95:10 | SSA phi read(self) | ssa.rb:90:1:103:3 | self (m12) |
| ssa.rb:94:3:95:10 | SSA phi read(self) | ssa.rb:95:5:95:10 | SSA read(self) |
| ssa.rb:94:3:95:10 | SSA phi read(x) | ssa.rb:91:3:91:3 | x |
| ssa.rb:94:3:95:10 | SSA phi read(x) | ssa.rb:95:10:95:10 | SSA read(x) |

View File

@@ -2,7 +2,7 @@ import codeql.ruby.AST
import codeql.ruby.CFG
import codeql.ruby.dataflow.SSA
import codeql.ruby.dataflow.internal.SsaImpl
import ExposedForTestingOnly
import Impl::TestAdjacentRefs as RefTest
query predicate definition(Ssa::Definition def, Variable v) { def.getSourceVariable() = v }
@@ -23,16 +23,20 @@ query predicate phi(Ssa::PhiNode phi, Variable v, Ssa::Definition input) {
phi.getSourceVariable() = v and input = phi.getAnInput()
}
query predicate phiReadNode(PhiReadNode phi, Variable v) { phi.getSourceVariable() = v }
query predicate phiReadNode(RefTest::Ref phi, Variable v) {
phi.isPhiRead() and phi.getSourceVariable() = v
}
query predicate phiReadNodeRead(PhiReadNode phi, Variable v, CfgNode read) {
phi.getSourceVariable() = v and
exists(BasicBlock bb, int i |
ssaDefReachesReadExt(v, phi, bb, i) and
query predicate phiReadNodeFirstRead(RefTest::Ref phi, Variable v, CfgNode read) {
exists(RefTest::Ref r, BasicBlock bb, int i |
phi.isPhiRead() and
RefTest::adjacentRefRead(phi, r) and
r.accessAt(bb, i, v) and
read = bb.getNode(i)
)
}
query predicate phiReadInput(PhiReadNode phi, DefinitionExt inp) {
phiHasInputFromBlockExt(phi, inp, _)
query predicate phiReadInput(RefTest::Ref phi, RefTest::Ref inp) {
phi.isPhiRead() and
RefTest::adjacentRefPhi(inp, phi)
}