Skip to content

x/vuln: vulnerability scan crashes #63146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
whereswaldon opened this issue Sep 21, 2023 · 11 comments
Closed

x/vuln: vulnerability scan crashes #63146

whereswaldon opened this issue Sep 21, 2023 · 11 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. vulncheck or vulndb Issues for the x/vuln or x/vulndb repo WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.

Comments

@whereswaldon
Copy link
Contributor

What version of Go are you using (go version)?

$ go version
go version go1.21.1 linux/amd64

Does this issue reproduce at the latest version of golang.org/x/vuln?

Yes

$ govulncheck --version
Go: go1.21.1
Scanner: [email protected]
DB: https://vuln.go.dev
DB updated: 2023-09-20 21:55:11 +0000 UTC

No vulnerabilities found.

Share feedback at https://go.dev/s/govulncheck-feedback.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/chris/.cache/go-build'
GOENV='/home/chris/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/chris/Code/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/chris/Code/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/chris/.local/lib/go-1.21.1'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/chris/.local/lib/go-1.21.1/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.1'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/chris/Code//go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build931040375=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I tried to scan a large repo for vulnerabilities, but govulncheck just panicked. Sadly, the repo is not open source, so I can only provide the stack trace.

$ govulncheck ./...
Scanning your code and 511 packages across 65 dependent modules for known vulnerabilities...

panic: interface conversion: types.Type is *types.Interface, not *types.Struct

goroutine 7887 [running]:
golang.org/x/tools/go/callgraph/vta.field.Type({{0x96ed48?, 0xc03e39d410?}, 0xc0d917f8f0?})
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:109 +0x72
golang.org/x/tools/go/callgraph/vta.(*builder).representative(0xc0d917fc08, {0x96f4f0, 0xc0e0c24450})
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:770 +0x3e
golang.org/x/tools/go/callgraph/vta.(*builder).addInFlowEdge(0xc0d917fc08, {0x96f4f0, 0xc0e0c24450}, {0x96f2e8, 0xc0e0c284c0})
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:731 +0x5c
golang.org/x/tools/go/callgraph/vta.(*builder).fieldAddr(0xc0d917fc08?, 0xc09a0a3560)
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:441 +0xc5
golang.org/x/tools/go/callgraph/vta.(*builder).instr(0xc0d917faf0?, {0x972c40?, 0xc09a0a3560?})
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:350 +0x259
golang.org/x/tools/go/callgraph/vta.(*builder).fun(...)
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:300
golang.org/x/tools/go/callgraph/vta.(*builder).visit(0xc0d917fc08, 0x50?)
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:292 +0x1ae
golang.org/x/tools/go/callgraph/vta.typePropGraph(...)
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:266
golang.org/x/tools/go/callgraph/vta.CallGraph(0xc0d917fee0?, 0xc0cd384120)
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/vta.go:75 +0xe5
golang.org/x/vuln/internal/vulncheck.callGraph({0x971400, 0xc009763090}, 0xc0640f4240, {0xc0cd370000, 0x863, 0xc00023f180?})
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/internal/vulncheck/utils.go:81 +0x23d
golang.org/x/vuln/internal/vulncheck.Source.func1()
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/internal/vulncheck/source.go:65 +0xef
created by golang.org/x/vuln/internal/vulncheck.Source in goroutine 6
        /home/chris/Code/go/pkg/mod/golang.org/x/[email protected]/internal/vulncheck/source.go:61 +0x2d9

What did you expect to see?

A report about vulnerable dependencies.

What did you see instead?

A crash.

@whereswaldon whereswaldon added the vulncheck or vulndb Issues for the x/vuln or x/vulndb repo label Sep 21, 2023
@gopherbot gopherbot modified the milestones: Unreleased, vuln/unplanned Sep 21, 2023
@timothy-king
Copy link
Contributor

timothy-king commented Sep 21, 2023

Thank you for the report. This is going to be hard to fix without a reproducer. Would it be possible for you to get us a minimized reproducer? The most helpful thing would be to get a simplified function body of the function that is crashing. (Debugging *builder.fun in a debugger or printf debugging via f.Prog.Fset.Position(f.Pos()) should get you the function.)

My current hunch from that stack trace is that (*vta.builder).fieldAddr may need to be updated to take a core type. That unfortunately probably means something else is off as I don't know why the type propagation graph would be being built for the generic code. If you are willing to get your hands a bit dirty you can see if this fixes you:

diff --git a/go/callgraph/vta/graph.go b/go/callgraph/vta/graph.go
index 2537123f4..4aaf3154a 100644
--- a/go/callgraph/vta/graph.go
+++ b/go/callgraph/vta/graph.go
@@ -106,7 +106,7 @@ type field struct {
 }
 
 func (f field) Type() types.Type {
-       s := f.StructType.Underlying().(*types.Struct)
+       s := typeparams.CoreType(f.StructType).(*types.Struct)
        return s.Field(f.index).Type()
 }
 
@@ -434,7 +434,7 @@ func (b *builder) field(f *ssa.Field) {
 }
 
 func (b *builder) fieldAddr(f *ssa.FieldAddr) {
-       t := f.X.Type().Underlying().(*types.Pointer).Elem()
+       t := typeparams.CoreType(f.X.Type()).(*types.Pointer).Elem()
 
        // Since we are getting pointer to a field, make a bidirectional edge.
        fnode := field{StructType: t, index: f.Field}

@thanm thanm added WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Sep 25, 2023
@iwittkau
Copy link

I'm seeing this bug too and I narrowed it down to a package's test files (using -test).

@timothy-king any tips on how to find the exact line that triggers this panic so I can provide a sample that reproduces the bug?

@iwittkau
Copy link

iwittkau commented Oct 17, 2023

I think this must be a race condition because I found the file that triggers the panic reliably locally and in a CI pipeline.

But when I extract the structs and interfaces to a sample project it works fine.

@iwittkau
Copy link

Never mind my previous comments, got something:

package test

import (
	"testing"
)

type type1 struct{ embedded }

type type2 struct{ embedded }

type oneOrTwo interface {
	type1 | type2
}

type embedded struct {
	id string
}

func generate[T oneOrTwo]() (T, error) {
	return T{embedded{}}, nil
}

func MustGenerate[T oneOrTwo](tb testing.TB) T {
	tb.Helper()
	result, err := generate[T]()
	if err != nil {
		tb.Fatalf("generating: %v", err)
	}
	return result
}

Add this as a package to project and run

govulncheck -version ./test

Output

$ govulncheck -version ./test
Go: go1.21.3
Scanner: [email protected]
DB: https://vuln.go.dev
DB updated: 2023-10-16 19:30:55 +0000 UTC

Scanning your code and 54 packages across 0 dependent modules for known vulnerabilities...

panic: interface conversion: types.Type is *types.Interface, not *types.Struct

goroutine 726 [running]:
golang.org/x/tools/go/callgraph/vta.field.Type({{0x104c1db28?, 0x14002452600?}, 0x1400c669928?})
        /home/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:109 +0x88
golang.org/x/tools/go/callgraph/vta.hasInFlow({0x104c1e2d0?, 0x1400ccbb020?})
        /home/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/utils.go:51 +0x6c
golang.org/x/tools/go/callgraph/vta.(*builder).addInFlowEdge(0x1400c669c00, {0x104c1e208, 0x14001ad5640}, {0x104c1e2d0, 0x1400ccbb020})
        /home/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:730 +0x38
golang.org/x/tools/go/callgraph/vta.(*builder).fieldAddr(0x1400c669a58?, 0x14003455680)
        /home/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:442 +0x100
golang.org/x/tools/go/callgraph/vta.(*builder).instr(0x1400c669ae8?, {0x104c21960?, 0x14003455680?})
        /home/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:350 +0x250
golang.org/x/tools/go/callgraph/vta.(*builder).fun(...)
        /home/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:300
golang.org/x/tools/go/callgraph/vta.(*builder).visit(0x1400c669c00, 0x104b83920?)
        /home/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:292 +0x19c
golang.org/x/tools/go/callgraph/vta.typePropGraph(...)
        /home/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/graph.go:266
golang.org/x/tools/go/callgraph/vta.CallGraph(0x1400c669ed8?, 0x1400be9d090)
        /home/go/pkg/mod/golang.org/x/[email protected]/go/callgraph/vta/vta.go:75 +0x8c
golang.org/x/vuln/internal/vulncheck.callGraph({0x104c20100, 0x140043629b0}, 0x140062bc000, {0x1400be9d080, 0x2, 0x140001ee000?})
        /home/go/pkg/mod/golang.org/x/[email protected]/internal/vulncheck/utils.go:81 +0x1bc
golang.org/x/vuln/internal/vulncheck.Source.func1()
        /home/go/pkg/mod/golang.org/x/[email protected]/internal/vulncheck/source.go:65 +0xe4
created by golang.org/x/vuln/internal/vulncheck.Source in goroutine 6
        /home/go/pkg/mod/golang.org/x/[email protected]/internal/vulncheck/source.go:61 +0x254

@timothy-king your suggested change actually fixes the panic!

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/536035 mentions this issue: go/callgraph/vta: use core type for struct fields

@timothy-king
Copy link
Contributor

That reproducer is perfect. Thanks.

@iwittkau
Copy link

@timothy-king It still crashes because the x/tools module in vuln needs to be updated to the fixed version.

@timothy-king
Copy link
Contributor

timothy-king commented Nov 21, 2023

Updated x/vuln. Sync past https://go.dev/cl/544295.

@iwittkau
Copy link

Thank you!

@iwittkau
Copy link

iwittkau commented Jan 9, 2024

@master works, but there's still no version tagged including this fix, resulting in panics when using the @latest version:

go install golang.org/x/vuln/cmd/govulncheck@latest

panics, vs.

go install golang.org/x/vuln/cmd/govulncheck@master

which doesn't.

@iwittkau
Copy link

It works with v1.0.3 now!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. vulncheck or vulndb Issues for the x/vuln or x/vulndb repo WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

5 participants