mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
cmd/go: respect group sticky bit on install.
When installing a package to a different directory using `go build`, `mv` cannot be used if the destination directory has the group sticky bit set. Instead, `cp` should be used to make sure the destination file has the correct permissions. Fixes golang/go#18878. Change-Id: I5423f559e7f84df080ed47816e19a22c6d00ab6d Reviewed-on: https://go-review.googlesource.com/36797 Run-TryBot: Chris Manghane <cmang@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
4e0f63940c
commit
e9bb9e597e
2 changed files with 65 additions and 0 deletions
|
@ -1655,6 +1655,15 @@ func (b *Builder) moveOrCopyFile(a *Action, dst, src string, perm os.FileMode, f
|
|||
// If we can update the mode and rename to the dst, do it.
|
||||
// Otherwise fall back to standard copy.
|
||||
|
||||
// If the destination directory has the group sticky bit set,
|
||||
// we have to copy the file to retain the correct permissions.
|
||||
// https://golang.org/issue/18878
|
||||
if fi, err := os.Stat(filepath.Dir(dst)); err == nil {
|
||||
if fi.IsDir() && (fi.Mode()&os.ModeSetgid) != 0 {
|
||||
return b.copyFile(a, dst, src, perm, force)
|
||||
}
|
||||
}
|
||||
|
||||
// The perm argument is meant to be adjusted according to umask,
|
||||
// but we don't know what the umask is.
|
||||
// Create a dummy file to find out.
|
||||
|
|
|
@ -5,10 +5,15 @@
|
|||
package work
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
|
@ -165,3 +170,54 @@ func pkgImportPath(pkgpath string) *load.Package {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
// When installing packages, the installed package directory should
|
||||
// respect the group sticky bit and group name of the destination
|
||||
// directory.
|
||||
// See https://golang.org/issue/18878.
|
||||
func TestRespectGroupSticky(t *testing.T) {
|
||||
if runtime.GOOS == "nacl" {
|
||||
t.Skip("can't set group sticky bit with chmod on nacl")
|
||||
}
|
||||
|
||||
var b Builder
|
||||
b.Init()
|
||||
|
||||
// Check that `cp` is called instead of `mv` by looking at the output
|
||||
// of `(*Builder).ShowCmd` afterwards as a sanity check.
|
||||
cfg.BuildX = true
|
||||
var cmdBuf bytes.Buffer
|
||||
b.Print = func(a ...interface{}) (int, error) {
|
||||
return cmdBuf.WriteString(fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
stickydir := path.Join(os.TempDir(), "GroupSticky")
|
||||
if err := os.Mkdir(stickydir, 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(stickydir)
|
||||
|
||||
// Mkdir doesn't always correctly set the group sticky bit.
|
||||
// Change stickydir's permissions to include group sticky bit.
|
||||
if err := os.Chmod(stickydir, 0755|os.ModeSetgid); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
pkgfile, err := ioutil.TempFile(b.WorkDir, "")
|
||||
if err != nil {
|
||||
t.Fatalf("ioutil.TempFile(%q): %v", b.WorkDir, err)
|
||||
}
|
||||
defer os.Remove(pkgfile.Name())
|
||||
defer pkgfile.Close()
|
||||
|
||||
stickyFile := filepath.Join(stickydir, "sticky")
|
||||
if err := b.moveOrCopyFile(nil, stickyFile, pkgfile.Name(), 0666, true); err != nil {
|
||||
t.Fatalf("moveOrCopyFile: %v", err)
|
||||
}
|
||||
|
||||
got := strings.TrimSpace(cmdBuf.String())
|
||||
want := b.fmtcmd("", "cp %s %s", pkgfile.Name(), stickyFile)
|
||||
if got != want {
|
||||
t.Fatalf("moveOrCopyFile(%q, %q): want %q, got %q", stickyFile, pkgfile.Name(), want, got)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue