[Go] Getting the resolved type of an argument #15591
-
Hi, I am trying to obtain the types of objects queried by the Get method of Kubernetes controllers for https://github.com/openshift/hypershift/tree/release-4.15 . I expect one well defined (and qualified) type per call to Get() like so: The codebase has 287 of such calls. The last argument can be passed several ways:
The following query works for the first case (but only returns 42 results over the 287 Get calls): from DataFlow::MethodCallNode call, AddressExpr arg, Type t
where
call.getTarget().hasQualifiedName("sigs.k8s.io/controller-runtime/pkg/client.Client", "Get") and
call.getArgument(2).asExpr() = arg and
t = arg.getOperand().getType()
select call, "Client calls $@ to obtain resource type $@", call, call.getTarget().getName(), t, t.getQualifiedName() A dataflow query sounds like what should solve the problem at hand but doing so returns several types per Get call, with some of the returned types making no sense at all: import go
import K8sControllerClient::K8sControllerClient
import Utils::Utils
module ResourceTypesFlow implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node.asExpr() instanceof ValueExpr }
predicate isSink(DataFlow::Node node) {
exists(DataFlow::MethodCallNode call |
call.getArgument(2) = node and
call.getTarget().hasQualifiedName("sigs.k8s.io/controller-runtime/pkg/client.Client", "Get")
)
}
predicate isBarrier(DataFlow::Node node) {
node.asExpr().getLocation().getFile().getBaseName().matches("%_wrapper.go") or
node.asExpr().getLocation().getFile().getBaseName().matches("zz_%.go")
}
}
module Flow = TaintTracking::Global<ResourceTypesFlow>;
from DataFlow::Node source, DataFlow::Node sink, DataFlow::MethodCallNode call, Type resourceType
where
Flow::flow(source, sink) and
call.getArgument(2) = sink and
resourceType = source.getType()
select source, "Kubernetes Controller Client calls $@ to obtain resource $@ ($@)", call,
call.getCalleeName() + "()", resourceType, resourceType.getQualifiedName(), source,
source.toString() I feel this should be a simple task, what am I missing here? Thanks. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
I suspect this might have to do with the K8sControllerClient module that you're importing-- I can't tell for sure without its source code, but does it perhaps introduce models that would propagate dataflow between the different arguments of that Get call? Meanwhile, to do what you want I suspect you don't need dataflow at all. In your first argument you use If your concern is that you might have something like |
Beta Was this translation helpful? Give feedback.
I suspect this might have to do with the K8sControllerClient module that you're importing-- I can't tell for sure without its source code, but does it perhaps introduce models that would propagate dataflow between the different arguments of that Get call?
Meanwhile, to do what you want I suspect you don't need dataflow at all. In your first argument you use
arg.getOperand().getType()
, which assumes the argument is an address-of operator. Why not drop that assumption and instead usearg.getType().(PointerType).getBaseType()
to account for more kinds of expression?If your concern is that you might have something like
Get(..., GetResource())
whereGetResource
has a loose return type and you…