From 4a41da5bac1da4a71b237581ab30dd7a84c5bc55 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Thu, 16 Nov 2017 16:38:19 +1100 Subject: [PATCH] cmd/go: add TestACL Add test that verifies that go command produces executable that have security attributes of the target directory. Update #22343 Change-Id: Ieab02381927a2b09bee21c49c043b3298bd088e6 Reviewed-on: https://go-review.googlesource.com/78215 Reviewed-by: Brad Fitzpatrick --- src/cmd/go/go_windows_test.go | 81 +++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/cmd/go/go_windows_test.go b/src/cmd/go/go_windows_test.go index d8d04aaf49..aa68a19580 100644 --- a/src/cmd/go/go_windows_test.go +++ b/src/cmd/go/go_windows_test.go @@ -5,12 +5,14 @@ package main import ( + "fmt" "internal/testenv" "io/ioutil" "os" "os/exec" "path/filepath" "strings" + "syscall" "testing" ) @@ -54,3 +56,82 @@ func TestAbsolutePath(t *testing.T) { t.Fatalf("wrong output found: %v %v", err, string(output)) } } + +func isWindowsXP(t *testing.T) bool { + v, err := syscall.GetVersion() + if err != nil { + t.Fatalf("GetVersion failed: %v", err) + } + major := byte(v) + return major < 6 +} + +func runIcacls(t *testing.T, args ...string) string { + t.Helper() + out, err := exec.Command("icacls", args...).CombinedOutput() + if err != nil { + t.Fatalf("icacls failed: %v\n%v", err, string(out)) + } + return string(out) +} + +func runGetACL(t *testing.T, path string) string { + t.Helper() + cmd := fmt.Sprintf(`Get-Acl "%s" | Select -expand AccessToString`, path) + out, err := exec.Command("powershell", "-Command", cmd).CombinedOutput() + if err != nil { + t.Fatalf("Get-Acl failed: %v\n%v", err, string(out)) + } + return string(out) +} + +// For issue 22343: verify that executable file created by "go build" command +// has discretionary access control list (DACL) set as if the file +// was created in the destination directory. +func TestACL(t *testing.T) { + if isWindowsXP(t) { + t.Skip("Windows XP does not have powershell command") + } + + tmpdir, err := ioutil.TempDir("", "TestACL") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + newtmpdir := filepath.Join(tmpdir, "tmp") + err = os.Mkdir(newtmpdir, 0777) + if err != nil { + t.Fatal(err) + } + + // When TestACL/tmp directory is created, it will have + // the same security attributes as TestACL. + // Add Guest account full access to TestACL/tmp - this + // will make all files created in TestACL/tmp have different + // security attributes to the files created in TestACL. + runIcacls(t, newtmpdir, + "/grant", "guest:(oi)(ci)f", // add Guest user to have full access + ) + + src := filepath.Join(tmpdir, "main.go") + err = ioutil.WriteFile(src, []byte("package main; func main() { }\n"), 0644) + if err != nil { + t.Fatal(err) + } + exe := filepath.Join(tmpdir, "main.exe") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, src) + cmd.Env = append(os.Environ(), + "TMP="+newtmpdir, + "TEMP="+newtmpdir, + ) + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("go command failed: %v\n%v", err, string(out)) + } + + // exe file is expected to have the same security attributes as the src. + if got, expected := runGetACL(t, exe), runGetACL(t, src); got != expected { + t.Fatalf("expected Get-Acl output of \n%v\n, got \n%v\n", expected, got) + } +} -- 2.48.1