Skip to content

x/vuln: false positive for GO-2025-3408 #71484

Not planned
Not planned
@ping-localhost

Description

@ping-localhost

govulncheck version

Go: go1.23.5
Scanner: govulncheck@v1.1.4
DB: https://vuln.go.dev
DB updated: 2025-01-29 20:18:58 +0000 UTC

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

Yes

Output of go env in your module/workspace:

GO111MODULE='on'
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/mitchell/Library/Caches/go-build'
GOENV='/Users/mitchell/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/mitchell/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/mitchell/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/opt/go/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/opt/go/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.23.5'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/mitchell/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/dev/null'
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 -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/c6/4l4ylj_530z56dccw0b7_pq00000gn/T/go-build2006941850=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

Using github.com/mattermost/mattermost/server/public/model in my project, which has a dependency on github.com/hashicorp/yamux (which I don't use) causes govulncheck@v1.1.4 to imply that GO-2025-3408 affects me (via sync.Once which is called by time.LoadLocation).

Sample code

package main

import (
	"fmt"
	"time"

	"github.com/mattermost/mattermost/server/public/model"
)

func main() {
	// Use something that calls `sync.Once`
	netherlands, err := time.LoadLocation("Europe/Amsterdam")
	if err != nil {
		panic(err)
	}

	// Just use anything from the Mattermost package as an example
	post := &model.Post{Message: "Hello!", ChannelId: "ID"}

	// Output because we can
	fmt.Println(netherlands, post.Message)
}

Repository: https://github.com/ping-localhost/vuln-check-reproducible

What did you see happen?

[16:56:12] ➜  vuln-check-reproducible git:(master) govulncheck ./...                                  
=== Symbol Results ===

Vulnerability #1: GO-2025-3408
    DefaultConfig has dangerous defaults causing hung Read in
    github.com/hashicorp/yamux
  More info: https://pkg.go.dev/vuln/GO-2025-3408
  Module: github.com/hashicorp/yamux
    Found in: github.com/hashicorp/yamux@v0.1.1
    Fixed in: N/A
    Example traces found:
      #1: main.go:12:39: vuln.main calls time.LoadLocation, which eventually calls yamux.Client
      #2: main.go:12:39: vuln.main calls time.LoadLocation, which eventually calls yamux.DefaultConfig

Your code is affected by 1 vulnerability from 1 module.
This scan found no other vulnerabilities in packages you import or modules you
require.
Use '-show verbose' for more details.

What did you expect to see?

Since I never actually use Yamux, I do not expect the CVE to be picked up. Somewhere along the line govulncheck thinks that sync.Once.Do will call yamux.

Activity

zpavlinovic

zpavlinovic commented on Jan 30, 2025

@zpavlinovic
Contributor

How is this a false negative? Perhaps you mean a false positive?

changed the title [-]x/vuln: false negative for GO-2025-3408[/-] [+]x/vuln: false positive for GO-2025-3408[/+] on Jan 30, 2025
ping-localhost

ping-localhost commented on Jan 30, 2025

@ping-localhost
Author

How is this a false negative? Perhaps you mean a false positive?

You're totally correct. I properly named my repository and then messed up in the issue. 🤦‍♂️

My bad!

zpavlinovic

zpavlinovic commented on Jan 30, 2025

@zpavlinovic
Contributor

Since I never actually use Yamux, I do not expect the CVE to be picked up.

govulncheck does not check just the modules you directly use. It also analyzes transitive dependencies. This is absolutely necessary as such dependencies can also be vulnerable and if your code eventually exercises them, your code is also vulnerable.

Somewhere along the line govulncheck thinks that sync.Once.Do will call yamux.

It could be that your code indeed does not call yamux. It is hard for me to tell, but it looks that way. In general, govulncheck can have false positives (this is an inherent property of all vulnerability checking tools). We are working on providing suppression mechanisms for false positives.

seankhliao

seankhliao commented on Jan 30, 2025

@seankhliao
Member

I believe this is the same as #69446 (closed without resolution).
where govulncheck lacks context sensitvity #69446 (comment)

The trace is as below, which can't be right (the standard library won't call an external dependency).

Vulnerability #1: GO-2025-3408
    DefaultConfig has dangerous defaults causing hung Read in
    github.com/hashicorp/yamux
  More info: https://pkg.go.dev/vuln/GO-2025-3408
  Module: github.com/hashicorp/yamux
    Found in: github.com/hashicorp/yamux@v0.1.1
    Fixed in: N/A
    Example traces found:
      #1: for function github.com/hashicorp/yamux.Client
        main @ github.com/ping-localhost/vuln-check-reproducible/main.go:12:39
        LoadLocation @ stdlib/src/time/zoneinfo.go:675:17
        Once.Do @ stdlib/src/sync/once.go:69:11
        Once.doSlow @ stdlib/src/sync/once.go:78:4
        getGRPCMuxer @ github.com/hashicorp/go-plugin/client.go:1153:48
        NewGRPCClientMuxer @ github.com/hashicorp/go-plugin/internal/grpcmux/grpc_client_muxer.go:53:27
        Client @ github.com/hashicorp/yamux/mux.go:105:6
      #2: for function github.com/hashicorp/yamux.DefaultConfig
        main @ github.com/ping-localhost/vuln-check-reproducible/main.go:12:39
        LoadLocation @ stdlib/src/time/zoneinfo.go:675:17
        Once.Do @ stdlib/src/sync/once.go:69:11
        Once.doSlow @ stdlib/src/sync/once.go:78:4
        getGRPCMuxer @ github.com/hashicorp/go-plugin/client.go:1153:48
        NewGRPCClientMuxer @ github.com/hashicorp/go-plugin/internal/grpcmux/grpc_client_muxer.go:48:28
        DefaultConfig @ github.com/hashicorp/yamux/mux.go:58:6
ping-localhost

ping-localhost commented on Jan 30, 2025

@ping-localhost
Author

@seankhliao thank you for posting the trace. It is exactly why I opened this issue, as that shouldn't happen.

zpavlinovic

zpavlinovic commented on Jan 30, 2025

@zpavlinovic
Contributor

@seankhliao thank you for posting the trace. It is exactly why I opened this issue, as that shouldn't happen.

We currently don't have immediate plans on improving the precision of govulncheck. (Due to the nature of the problem, this can in principle be done indefinitely). We are instead focusing on providing supression mechanisms.

self-assigned this
on Jan 30, 2025
added
WaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.
on Jan 30, 2025
ping-localhost

ping-localhost commented on Feb 3, 2025

@ping-localhost
Author

I don't understand why you've added WaitingForInfo, since all the information has been provided AFAIK. 😅

Furthermore, I don't want to ignore this CVE, since that sets a bad precedent. It would be much better if the detection is fixed, since there is no way that a core package like sync would ever call an external package.

zpavlinovic

zpavlinovic commented on Feb 3, 2025

@zpavlinovic
Contributor

I've added the label since it will automatically close the issue unless some other information shows up that would make us keep it open.

Again, we don't have current plans on improving the precision of govulncheck. We could do that in principle forever since it is, as all other vulnerability tools, trying to solve an undecidable problem. Our focus is now on suppression mechanisms.

... since there is no way that a core package like sync would ever call an external package.

I am not sure what this means. sync.Once.Do takes a function as input. That function can be defined in the user package or an external package. I actually think that hashicorp's getGRPCMuxer is passed to sync.Once.Do somewhere in the dependency code, but it is not passed via your main -> time.LoadLocation path. Roughly speaking, this is where the analysis trips. It does not have the necessary context tracking the provenance of all values passed to sync.Once.Do, which is really hard.

ping-localhost

ping-localhost commented on Feb 4, 2025

@ping-localhost
Author

For those that are also running into this issue (and would like to keep their CVE checks active), I've switched to using govulncheck -mode=binary, since that doesn't trigger an actual CVE error.

Source mode (default)

[12:41:08] ➜  vuln-check-reproducible git:(master) govulncheck ./...                                  
=== Symbol Results ===

Vulnerability #1: GO-2025-3408
    DefaultConfig has dangerous defaults causing hung Read in
    github.com/hashicorp/yamux
  More info: https://pkg.go.dev/vuln/GO-2025-3408
  Module: github.com/hashicorp/yamux
    Found in: github.com/hashicorp/yamux@v0.1.1
    Fixed in: N/A
    Example traces found:
      #1: main.go:12:39: vuln.main calls time.LoadLocation, which eventually calls yamux.Client
      #2: main.go:12:39: vuln.main calls time.LoadLocation, which eventually calls yamux.DefaultConfig

Your code is affected by 1 vulnerability from 1 module.
This scan found no other vulnerabilities in packages you import or modules you
require.
Use '-show verbose' for more details.

Binary mode

[12:41:24] ➜  vuln-check-reproducible git:(master) govulncheck -mode=binary vuln-check-reproducible 
=== Symbol Results ===

No vulnerabilities found.

Your code is affected by 0 vulnerabilities.
This scan also found 1 vulnerability in packages you import and 0
vulnerabilities in modules you require, but your code doesn't appear to call
these vulnerabilities.
Use '-show verbose' for more details.
dduzgun-security

dduzgun-security commented on Feb 6, 2025

@dduzgun-security

For your info, GO-2025-3408 got withdrawn. More details here: golang/vulndb#3453

seankhliao

seankhliao commented on Feb 7, 2025

@seankhliao
Member

time uses sync.Once in a single place, with a private variable.

https://go.googlesource.com/go/+/7a2f757c521d9af201c6d3463a0e203c4104d5aa/src/time/zoneinfo.go#646
https://go.googlesource.com/go/+/7a2f757c521d9af201c6d3463a0e203c4104d5aa/src/time/zoneinfo.go#675

the reproducer uses mattermost, which uses hashicorp/go-plugin, which pulls in yamux through

https://github.com/hashicorp/go-plugin/blob/5b05b3e78c6c3e4e0b8f21a9921cbd739ba72f2a/client.go#L1152-L1154

sync will call an closures passed to it, but it really shouldn't trigger with time, otherwise we'll get false positive reports everytime a vulnerable symbol is used in sync.Once closure somewhere.

Even if there are no immediate plans to fix, given that this is a repeat issue, govulncheck could probably be more explicit in its limitations, perhaps a few examples for "Govulncheck analyzes function pointer and interface calls conservatively, which may result in false positives or inaccurate call stacks in some cases.
"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

WaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.vulncheck or vulndbIssues for the x/vuln or x/vulndb repo

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @zpavlinovic@gopherbot@seankhliao@ping-localhost@dduzgun-security

      Issue actions

        x/vuln: false positive for GO-2025-3408 · Issue #71484 · golang/go