delete getKernelMethod and don't special-case the methodName on super-calls in the Kernel model

This commit is contained in:
erik-krogh
2022-12-07 13:14:48 +01:00
parent 52c0afa03f
commit 360a99f026
4 changed files with 15 additions and 29 deletions

View File

@@ -18,34 +18,20 @@ module Kernel {
* providing a specific receiver as in `Kernel.exit`.
*/
class KernelMethodCall extends DataFlow::CallNode {
string methodName;
KernelMethodCall() {
this = API::getTopLevelMember("Kernel").getAMethodCall(methodName)
this = API::getTopLevelMember("Kernel").getAMethodCall(_)
or
this.asExpr().getExpr() instanceof UnknownMethodCall and
(
methodName = super.getMethodName()
or
this.asExpr().getExpr() instanceof SuperCall and
methodName = this.asExpr().getExpr().getEnclosingCallable().(MethodBase).getName()
) and
(
this.getReceiver().asExpr().getExpr() instanceof SelfVariableAccess and
isPrivateKernelMethod(methodName)
isPrivateKernelMethod(super.getMethodName())
or
this.asExpr().getExpr() instanceof SuperCall and
isPrivateKernelMethod(methodName)
isPrivateKernelMethod(super.getMethodName())
or
isPublicKernelMethod(methodName)
isPublicKernelMethod(super.getMethodName())
)
}
/**
* Gets which method of `Kernel` is called.
* Works even when the call is a `super(...)` call.
*/
string getKernelMethod() { result = methodName }
}
/**
@@ -110,7 +96,7 @@ module Kernel {
* Ruby documentation: https://docs.ruby-lang.org/en/3.0.0/Kernel.html#method-i-system
*/
class KernelSystemCall extends SystemCommandExecution::Range instanceof KernelMethodCall {
KernelSystemCall() { this.getKernelMethod() = "system" }
KernelSystemCall() { this.getMethodName() = "system" }
override DataFlow::Node getAnArgument() { result = super.getArgument(_) }
@@ -126,7 +112,7 @@ module Kernel {
* Ruby documentation: https://docs.ruby-lang.org/en/3.0.0/Kernel.html#method-i-exec
*/
class KernelExecCall extends SystemCommandExecution::Range instanceof KernelMethodCall {
KernelExecCall() { this.getKernelMethod() = "exec" }
KernelExecCall() { this.getMethodName() = "exec" }
override DataFlow::Node getAnArgument() { result = super.getArgument(_) }
@@ -147,7 +133,7 @@ module Kernel {
* ```
*/
class KernelSpawnCall extends SystemCommandExecution::Range instanceof KernelMethodCall {
KernelSpawnCall() { this.getKernelMethod() = "spawn" }
KernelSpawnCall() { this.getMethodName() = "spawn" }
override DataFlow::Node getAnArgument() { result = super.getArgument(_) }
@@ -166,7 +152,7 @@ module Kernel {
* ```
*/
class EvalCallCodeExecution extends CodeExecution::Range, KernelMethodCall {
EvalCallCodeExecution() { this.getKernelMethod() = "eval" }
EvalCallCodeExecution() { this.getMethodName() = "eval" }
override DataFlow::Node getCode() { result = this.getArgument(0) }
}
@@ -180,7 +166,7 @@ module Kernel {
* ```
*/
class SendCallCodeExecution extends CodeExecution::Range, KernelMethodCall {
SendCallCodeExecution() { this.getKernelMethod() = "send" }
SendCallCodeExecution() { this.getMethodName() = "send" }
override DataFlow::Node getCode() { result = this.getArgument(0) }
@@ -200,15 +186,15 @@ module Kernel {
/** A call to e.g. `Kernel.load` that accesses a file. */
private class KernelFileAccess extends FileSystemAccess::Range instanceof KernelMethodCall {
KernelFileAccess() {
super.getKernelMethod() = ["load", "require", "require_relative", "autoload", "autoload?"]
super.getMethodName() = ["load", "require", "require_relative", "autoload", "autoload?"]
}
override DataFlow::Node getAPathArgument() {
result = super.getArgument(0) and
super.getKernelMethod() = ["load", "require", "require_relative"]
super.getMethodName() = ["load", "require", "require_relative"]
or
result = super.getArgument(1) and
super.getKernelMethod() = ["autoload", "autoload?"]
super.getMethodName() = ["autoload", "autoload?"]
}
}
}

View File

@@ -29,7 +29,7 @@ DataFlow::Node fileInstanceInstantiation() {
result = API::getTopLevelMember("File").getAMethodCall(["open", "try_convert"])
or
// Calls to `Kernel.open` can yield `File` instances
result.(KernelMethodCall).getKernelMethod() = "open" and
result.(KernelMethodCall).getMethodName() = "open" and
// Assume that calls that don't invoke shell commands will instead open
// a file.
not pathArgSpawnsSubprocess(result.(KernelMethodCall).getArgument(0).asExpr().getExpr())

View File

@@ -13,7 +13,7 @@ class AmbiguousPathCall extends DataFlow::CallNode {
string name;
AmbiguousPathCall() {
this.(KernelMethodCall).getKernelMethod() = "open" and
this.(KernelMethodCall).getMethodName() = "open" and
name = "Kernel.open"
or
this = API::getTopLevelMember("IO").getAMethodCall("read") and

View File

@@ -42,7 +42,7 @@ module StackTraceExposure {
* A call to `Kernel#caller`, considered as a flow source.
*/
class KernelCallerCall extends Source instanceof Kernel::KernelMethodCall {
KernelCallerCall() { super.getKernelMethod() = "caller" }
KernelCallerCall() { super.getMethodName() = "caller" }
}
/**