1
0
mirror of https://github.com/golang/go synced 2024-11-12 04:00:23 -07:00

cmd/dist: save and restore original permissions in makeGOROOTUnwritable

Also log a message and skip the Chmods if running as root.

Updates #30316

Change-Id: Ifb68d06ce845275a72d64c808407e8609df270bc
Reviewed-on: https://go-review.googlesource.com/c/go/+/206757
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Bryan C. Mills 2019-11-12 10:18:06 -05:00
parent 99957b6930
commit fc7ee0ba2c

55
src/cmd/dist/test.go vendored
View File

@ -192,8 +192,13 @@ func (t *tester) run() {
} }
// On a few builders, make GOROOT unwritable to catch tests writing to it. // On a few builders, make GOROOT unwritable to catch tests writing to it.
restoreGOROOT := func() {}
if strings.HasPrefix(os.Getenv("GO_BUILDER_NAME"), "linux-") { if strings.HasPrefix(os.Getenv("GO_BUILDER_NAME"), "linux-") {
t.makeGOROOTUnwritable() if os.Getuid() == 0 {
log.Printf("Not making GOROOT unwritable: running as root, so permissions would have no effect.")
} else {
restoreGOROOT = t.makeGOROOTUnwritable()
}
} }
for _, dt := range t.tests { for _, dt := range t.tests {
@ -208,12 +213,15 @@ func (t *tester) run() {
if t.keepGoing { if t.keepGoing {
log.Printf("Failed: %v", err) log.Printf("Failed: %v", err)
} else { } else {
restoreGOROOT()
log.Fatalf("Failed: %v", err) log.Fatalf("Failed: %v", err)
} }
} }
} }
t.runPending(nil) t.runPending(nil)
restoreGOROOT()
timelog("end", "dist test") timelog("end", "dist test")
if t.failed { if t.failed {
fmt.Println("\nFAILED") fmt.Println("\nFAILED")
os.Exit(1) os.Exit(1)
@ -1423,34 +1431,47 @@ func (t *tester) packageHasBenchmarks(pkg string) bool {
// makeGOROOTUnwritable makes all $GOROOT files & directories non-writable to // makeGOROOTUnwritable makes all $GOROOT files & directories non-writable to
// check that no tests accidentally write to $GOROOT. // check that no tests accidentally write to $GOROOT.
func (t *tester) makeGOROOTUnwritable() { func (t *tester) makeGOROOTUnwritable() (undo func()) {
if os.Getenv("GO_BUILDER_NAME") == "" { dir := os.Getenv("GOROOT")
panic("not a builder") if dir == "" {
}
if os.Getenv("GOROOT") == "" {
panic("GOROOT not set") panic("GOROOT not set")
} }
err := filepath.Walk(os.Getenv("GOROOT"), func(name string, fi os.FileInfo, err error) error {
if err != nil { type pathMode struct {
return err path string
mode os.FileMode
} }
if !fi.Mode().IsRegular() && !fi.IsDir() { var dirs []pathMode // in lexical order
return nil
undo = func() {
for i := range dirs {
os.Chmod(dirs[i].path, dirs[i].mode) // best effort
} }
mode := fi.Mode() }
newMode := mode & ^os.FileMode(0222)
if newMode != mode { filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err := os.Chmod(name, newMode); err != nil { if err == nil {
return err mode := info.Mode()
if mode&0222 != 0 && (mode.IsDir() || mode.IsRegular()) {
dirs = append(dirs, pathMode{path, mode})
} }
} }
return nil return nil
}) })
// Run over list backward to chmod children before parents.
for i := len(dirs) - 1; i >= 0; i-- {
err := os.Chmod(dirs[i].path, dirs[i].mode&^0222)
if err != nil { if err != nil {
log.Fatalf("making builder's files read-only: %v", err) dirs = dirs[i:] // Only undo what we did so far.
undo()
log.Fatalf("failed to make GOROOT read-only: %v", err)
} }
} }
return undo
}
// shouldUsePrecompiledStdTest reports whether "dist test" should use // shouldUsePrecompiledStdTest reports whether "dist test" should use
// a pre-compiled go test binary on disk rather than running "go test" // a pre-compiled go test binary on disk rather than running "go test"
// and compiling it again. This is used by our slow qemu-based builder // and compiling it again. This is used by our slow qemu-based builder