How to connect two alias dataflow node in Go? #17329
-
I am new to dataflow library for Go. I want to automatically find the alias slice reference expression with same value when executing in Go. I have a program as follows: func main() {
var s []int
s[0] = nil
s = s[1:]
} Is there any dataflow predicates I can use in dataflow library for Go to connect I tried two functions, import go
import DataFlow
predicate indexOfSlice(IndexExpr sliceIdx, SliceExpr slice) {
localFlow(exprNode(sliceIdx), exprNode(slice.getBase()))
}
from IndexExpr sliceIdx, SliceExpr slice
where indexOfSlice(sliceIdx, slice)
select sliceIdx, slice The result of the above query contains nothing. import go
import DataFlow
from ExprNode s, Node d
where globalValueNumber(s) = globalValueNumber(d)
select s, d I don't find I don't know which predicate I can use to connect these two node. Is there any predicate? The conditions requested in the question can be relaxed, i.e. connecting It is not a good idea to test whether results of func foo() {
a := 2
x := b.f
x.g = &a
b.f.g = &a
} Obviously, |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
Hi @Lslightly, Thanks for your question. In the first scenario you should be able to connect For example,
The second example is much more complicated because you need to keep track of aliases and match access path to relate access paths. For example, to relate An overfitted, but possible useful starting point, example is: predicate isAliasedThroughAccessPath(SsaVariable alias, SsaVariable base, string path) {
exists(SelectorExpr selector | base.getAUse().isFirstNodeOf(selector.getBase+()) |
globalValueNumber(DataFlow::ssaNode(alias)) = globalValueNumber(DataFlow::exprNode(selector))
and getAccessPath(selector) = path
)
}
string getAccessPath(SelectorExpr e) {
if e.getBase() instanceof SelectorExpr then
exists(string root | root = getAccessPath(e.getBase())|
result = root + "." + e.getSelector().getName()
)
else
result = e.getBase().(VariableName) + "." + e.getSelector().getName()
}
predicate isAliasedSelector(SelectorExpr n, SelectorExpr m) {
exists(SsaVariable baseOfN, SsaVariable baseOfM, string path |
isAliasedThroughAccessPath(baseOfN, baseOfM, path)
and baseOfN.getAUse().isFirstNodeOf(n.getBase+()) and
baseOfM.getAUse().isFirstNodeOf(m.getBase+()) and
getAccessPath(m) = getAccessPath(n).regexpReplaceAll("^"+baseOfN.getSourceVariable().getName()+"\\.", path + ".")
)
}
from SelectorExpr n, SelectorExpr m
where isAliasedSelector(n, m)
select n, m I will also ask the Go team for suggestions, because they are our CodeQL Go experts. |
Beta Was this translation helpful? Give feedback.
Hi @Lslightly,
Thanks for your question.
In the first scenario you should be able to connect
s
withs[0]
ands[1:]
through anSSAVariable
and its uses.For example,
The second example is much more complicated because you need to keep track of aliases and match access path to relate access paths.
For example, to relate
x.g
andb.f.g
you can relatex
withb
throughb.f
and later matchx.g
withb.f.g
through substitution ofx
in the access path with the access pathb.f
.An overfitted, but possible useful starting point, example is: