cmd/go/internal/modfetch: do not use mangled version strings to construct module.VersionErrors

Better still would be to avoid passing around module.Version instances
with invalid Version strings in the first place, so that any time we
see a module.Version we know that it is actually a version of a module
(and not a structurally-similar datum with something else tacked on to
one of the fields). But that's a bigger cleanup for which I don't
currently have enough bandwidth.

Fixes #41060

Change-Id: I32fba5619105cbf67dd03691064c82b8ebb3ce18
Reviewed-on: https://go-review.googlesource.com/c/go/+/250951
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
Bryan C. Mills 2020-08-26 23:17:53 -04:00
parent 3b20d484fb
commit c00b708169
3 changed files with 19 additions and 3 deletions

View File

@ -503,6 +503,9 @@ func checkGoMod(path, version string, data []byte) error {
}
// checkModSum checks that the recorded checksum for mod is h.
//
// mod.Version may have the additional suffix "/go.mod" to request the checksum
// for the module's go.mod file only.
func checkModSum(mod module.Version, h string) error {
// We lock goSum when manipulating it,
// but we arrange to release the lock when calling checkSumDB,
@ -579,9 +582,16 @@ func addModSumLocked(mod module.Version, h string) {
// checkSumDB checks the mod, h pair against the Go checksum database.
// It calls base.Fatalf if the hash is to be rejected.
func checkSumDB(mod module.Version, h string) error {
modWithoutSuffix := mod
noun := "module"
if strings.HasSuffix(mod.Version, "/go.mod") {
noun = "go.mod"
modWithoutSuffix.Version = strings.TrimSuffix(mod.Version, "/go.mod")
}
db, lines, err := lookupSumDB(mod)
if err != nil {
return module.VersionError(mod, fmt.Errorf("verifying module: %v", err))
return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: %v", noun, err))
}
have := mod.Path + " " + mod.Version + " " + h
@ -591,7 +601,7 @@ func checkSumDB(mod module.Version, h string) error {
return nil
}
if strings.HasPrefix(line, prefix) {
return module.VersionError(mod, fmt.Errorf("verifying module: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+sumdbMismatch, h, db, line[len(prefix)-len("h1:"):]))
return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+sumdbMismatch, noun, h, db, line[len(prefix)-len("h1:"):]))
}
}
return nil

View File

@ -3,7 +3,7 @@ env GOSUMDB=$sumdb' '$proxy/sumdb-wrong
# download -json with version should print JSON on sumdb failure
! go mod download -json 'rsc.io/quote@<=v1.5.0'
stdout '"Error": ".*verifying module'
stdout '"Error": ".*verifying (module|go.mod)'
-- go.mod --
module m

View File

@ -15,6 +15,12 @@ stderr 'localhost.localdev/sumdb: h1:wrong'
stderr 'SECURITY ERROR\nThis download does NOT match the one reported by the checksum server.'
! go get -d rsc.io/sampler
! go get -d golang.org/x/text
go mod edit -require rsc.io/quote@v1.5.2
! go list all
stderr 'go: rsc.io/quote@v1.5.2: verifying go.mod: checksum mismatch'
stderr 'SECURITY ERROR\n'
rm go.sum
# switching to truthful sumdb detects timeline inconsistency