diff options
Diffstat (limited to 'src/syscall/exec_freebsd_test.go')
-rw-r--r-- | src/syscall/exec_freebsd_test.go | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/syscall/exec_freebsd_test.go b/src/syscall/exec_freebsd_test.go new file mode 100644 index 0000000..2e9513f --- /dev/null +++ b/src/syscall/exec_freebsd_test.go @@ -0,0 +1,98 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build freebsd + +package syscall_test + +import ( + "fmt" + "internal/testenv" + "os" + "os/exec" + "path/filepath" + "syscall" + "testing" + "unsafe" +) + +const ( + flagJailCreate = uintptr(0x1) +) + +func prepareJail(t *testing.T) (int, string) { + t.Helper() + + root := t.TempDir() + paramPath := []byte("path\x00") + conf := make([]syscall.Iovec, 4) + conf[0].Base = ¶mPath[0] + conf[0].SetLen(len(paramPath)) + p, err := syscall.BytePtrFromString(root) + if err != nil { + t.Fatal(err) + } + conf[1].Base = p + conf[1].SetLen(len(root) + 1) + + paramPersist := []byte("persist\x00") + conf[2].Base = ¶mPersist[0] + conf[2].SetLen(len(paramPersist)) + conf[3].Base = nil + conf[3].SetLen(0) + + id, _, err1 := syscall.Syscall(syscall.SYS_JAIL_SET, + uintptr(unsafe.Pointer(&conf[0])), uintptr(len(conf)), flagJailCreate) + if err1 != 0 { + t.Fatalf("jail_set: %v", err1) + } + t.Cleanup(func() { + _, _, err1 := syscall.Syscall(syscall.SYS_JAIL_REMOVE, id, 0, 0) + if err1 != 0 { + t.Errorf("failed to cleanup jail: %v", err) + } + }) + + return int(id), root +} + +func TestJailAttach(t *testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" { + jailed, err := syscall.SysctlUint32("security.jail.jailed") + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(2) + } + if jailed != 1 { + t.Fatalf("jailed = %d, want 1", jailed) + } + return + } + + testenv.MustHaveGoBuild(t) + // Make sure we are running as root, so we have permissions to create + // and remove jails. + if os.Getuid() != 0 { + t.Skip("kernel prohibits jail system calls in unprivileged process") + } + + jid, root := prepareJail(t) + + // Since jail attach does an implicit chroot to the jail's path, + // we need the binary there, and it must be statically linked. + x := filepath.Join(root, "syscall.test") + cmd := exec.Command(testenv.GoToolPath(t), "test", "-c", "-o", x, "syscall") + cmd.Env = append(os.Environ(), "CGO_ENABLED=0") + if o, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("Build of syscall in jail root failed, output %v, err %v", o, err) + } + + cmd = exec.Command("/syscall.test", "-test.run=TestJailAttach", "/") + cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1") + cmd.SysProcAttr = &syscall.SysProcAttr{Jail: jid} + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("Cmd failed with err %v, output: %s", err, out) + } +} |