When running capslock against one of my projects, I noticed some of the CAPABILITY_NETWORK classifications didn't seem to make sense. Digging into it further revealed that they were incorrect.
Running capslock at 29c2da0 against https://github.com/capnspacehook/egress-eddie/tree/faa23e15384d4a7f148e3bcb9fa30f3ab4d37d4c with capslock -packages github.com/capnspacehook/egress-eddie -output j displayed a few classifications like this:
{
"packageName": "egresseddie",
"capability": "CAPABILITY_NETWORK",
"depPath": "github.com/capnspacehook/egress-eddie.parseConfigBytes github.com/BurntSushi/toml.Decode (*github.com/BurntSushi/toml.Decoder).Decode (*github.com/BurntSushi/toml.MetaData).unify (*github.com/BurntSushi/toml.MetaData).unifyText (net.pipeAddr).String",
"path": [
{
"name": "github.com/capnspacehook/egress-eddie.parseConfigBytes"
},
{
"name": "github.com/BurntSushi/toml.Decode",
"site": {
"filename": "config.go",
"line": "90",
"column": "24"
}
},
{
"name": "(*github.com/BurntSushi/toml.Decoder).Decode",
"site": {
"filename": "decode.go",
"line": "36",
"column": "51"
}
},
{
"name": "(*github.com/BurntSushi/toml.MetaData).unify",
"site": {
"filename": "decode.go",
"line": "169",
"column": "21"
}
},
{
"name": "(*github.com/BurntSushi/toml.MetaData).unifyText",
"site": {
"filename": "decode.go",
"line": "213",
"column": "22"
}
},
{
"name": "(net.pipeAddr).String",
"site": {
"filename": "decode.go",
"line": "513",
"column": "19"
}
}
],
"packageDir": "github.com/capnspacehook/egress-eddie",
"capabilityType": "CAPABILITY_TYPE_TRANSITIVE"
}
capslock seems to think toml.Decode is calling (net.pipeAddr).String eventually, but digging into the source reveals this is unlikely. (*github.com/BurntSushi/toml.MetaData).unifyText uses a type switch to create a string from an argument of type any. In the fmt.Stringer case capslock thinks that the now known fmt.Stringer type is the type net.pipeAddr. Source of the final call in the stack: https://github.com/BurntSushi/toml/blob/v1.2.1/decode.go#L513.
I understand that fmt.Stringer is an interface and apparently net.pipeAddr satisfies it, but it seems like capslock is assuming the concrete type of the fmt.Stringer here.
EDIT: after looking into this a bit more it seems this is just what golang.org/x/tools/go/ssa and golang.org/x/tools/go/callgraph reports and I'm not sure how difficult detecting this situation would be.
I tried to create a minimal reproducer the just called toml.Decode and some net functions so they would be loaded, but couldn't reproduce the same behavior unfortunately.
Thanks for building and open sourcing this tool, I've wanted something like this for a long time!
When running capslock against one of my projects, I noticed some of the
CAPABILITY_NETWORKclassifications didn't seem to make sense. Digging into it further revealed that they were incorrect.Running capslock at 29c2da0 against https://github.com/capnspacehook/egress-eddie/tree/faa23e15384d4a7f148e3bcb9fa30f3ab4d37d4c with
capslock -packages github.com/capnspacehook/egress-eddie -output jdisplayed a few classifications like this:{ "packageName": "egresseddie", "capability": "CAPABILITY_NETWORK", "depPath": "github.com/capnspacehook/egress-eddie.parseConfigBytes github.com/BurntSushi/toml.Decode (*github.com/BurntSushi/toml.Decoder).Decode (*github.com/BurntSushi/toml.MetaData).unify (*github.com/BurntSushi/toml.MetaData).unifyText (net.pipeAddr).String", "path": [ { "name": "github.com/capnspacehook/egress-eddie.parseConfigBytes" }, { "name": "github.com/BurntSushi/toml.Decode", "site": { "filename": "config.go", "line": "90", "column": "24" } }, { "name": "(*github.com/BurntSushi/toml.Decoder).Decode", "site": { "filename": "decode.go", "line": "36", "column": "51" } }, { "name": "(*github.com/BurntSushi/toml.MetaData).unify", "site": { "filename": "decode.go", "line": "169", "column": "21" } }, { "name": "(*github.com/BurntSushi/toml.MetaData).unifyText", "site": { "filename": "decode.go", "line": "213", "column": "22" } }, { "name": "(net.pipeAddr).String", "site": { "filename": "decode.go", "line": "513", "column": "19" } } ], "packageDir": "github.com/capnspacehook/egress-eddie", "capabilityType": "CAPABILITY_TYPE_TRANSITIVE" }capslock seems to think
toml.Decodeis calling(net.pipeAddr).Stringeventually, but digging into the source reveals this is unlikely.(*github.com/BurntSushi/toml.MetaData).unifyTextuses a type switch to create a string from an argument of typeany. In thefmt.Stringercase capslock thinks that the now knownfmt.Stringertype is the typenet.pipeAddr. Source of the final call in the stack: https://github.com/BurntSushi/toml/blob/v1.2.1/decode.go#L513.I understand that
fmt.Stringeris an interface and apparentlynet.pipeAddrsatisfies it, but it seems like capslock is assuming the concrete type of thefmt.Stringerhere.EDIT: after looking into this a bit more it seems this is just what
golang.org/x/tools/go/ssaandgolang.org/x/tools/go/callgraphreports and I'm not sure how difficult detecting this situation would be.I tried to create a minimal reproducer the just called
toml.Decodeand somenetfunctions so they would be loaded, but couldn't reproduce the same behavior unfortunately.Thanks for building and open sourcing this tool, I've wanted something like this for a long time!