| | |
| | |
| | |
| |
|
| | package exec_test |
| |
|
| | import ( |
| | "errors" |
| | "internal/syscall/unix" |
| | "internal/testenv" |
| | "os" |
| | "os/exec" |
| | "path/filepath" |
| | "syscall" |
| | "testing" |
| | ) |
| |
|
| | func TestFindExecutableVsNoexec(t *testing.T) { |
| | t.Parallel() |
| |
|
| | |
| | if !unix.KernelVersionGE(5, 8) { |
| | t.Skip("requires Linux kernel v5.8 with faccessat2(2) syscall") |
| | } |
| |
|
| | tmp := t.TempDir() |
| |
|
| | |
| | err := syscall.Mount("tmpfs", tmp, "tmpfs", 0, "") |
| | if testenv.SyscallIsNotSupported(err) { |
| | |
| | |
| | t.Skipf("requires ability to mount tmpfs (%v)", err) |
| | } else if err != nil { |
| | t.Fatalf("mount %s failed: %v", tmp, err) |
| | } |
| | t.Cleanup(func() { |
| | if err := syscall.Unmount(tmp, 0); err != nil { |
| | t.Error(err) |
| | } |
| | }) |
| |
|
| | |
| | path := filepath.Join(tmp, "program") |
| | err = os.WriteFile(path, []byte("#!/bin/sh\necho 123\n"), 0o755) |
| | if err != nil { |
| | t.Fatal(err) |
| | } |
| |
|
| | |
| | _, err = exec.LookPath(path) |
| | if err != nil { |
| | t.Fatalf("LookPath: got %v, want nil", err) |
| | } |
| |
|
| | for { |
| | err = exec.Command(path).Run() |
| | if err == nil { |
| | break |
| | } |
| | if errors.Is(err, syscall.ETXTBSY) { |
| | |
| | |
| | |
| | |
| | |
| | } else { |
| | t.Fatalf("exec: got %v, want nil", err) |
| | } |
| | } |
| |
|
| | |
| | err = syscall.Mount("", tmp, "", syscall.MS_REMOUNT|syscall.MS_NOEXEC, "") |
| | if testenv.SyscallIsNotSupported(err) { |
| | t.Skipf("requires ability to re-mount tmpfs (%v)", err) |
| | } else if err != nil { |
| | t.Fatalf("remount %s with noexec failed: %v", tmp, err) |
| | } |
| |
|
| | if err := exec.Command(path).Run(); err == nil { |
| | t.Fatal("exec on noexec filesystem: got nil, want error") |
| | } |
| |
|
| | _, err = exec.LookPath(path) |
| | if err == nil { |
| | t.Fatalf("LookPath: got nil, want error") |
| | } |
| | } |
| |
|