1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
20 "golang.org/x/sys/unix"
23 func TestSysctlUint64(t *testing.T) {
24 _, err := unix.SysctlUint64("vm.swap_total")
30 // FIXME: Infrastructure for launching tests in subprocesses stolen from openbsd_test.go - refactor?
31 // testCmd generates a proper command that, when executed, runs the test
32 // corresponding to the given key.
34 type testProc struct {
35 fn func() // should always exit instead of returning
36 arg func(t *testing.T) string // generate argument for test
37 cleanup func(arg string) error // for instance, delete coredumps from testing pledge
38 success bool // whether zero-exit means success or failure
42 testProcs = map[string]testProc{}
48 optName = "sys-unix-internal-procname"
49 optArg = "sys-unix-internal-arg"
53 flag.StringVar(&procName, optName, "", "internal use only")
54 flag.StringVar(&procArg, optArg, "", "internal use only")
58 func testCmd(procName string, procArg string) (*exec.Cmd, error) {
59 exe, err := filepath.Abs(os.Args[0])
63 cmd := exec.Command(exe, "-"+optName+"="+procName, "-"+optArg+"="+procArg)
64 cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
68 // ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
69 // a testProc with a key.
70 func ExitsCorrectly(t *testing.T, procName string) {
71 s := testProcs[procName]
76 c, err := testCmd(procName, arg)
77 defer func(arg string) {
78 if err := s.cleanup(arg); err != nil {
79 t.Fatalf("Failed to run cleanup for %s %s %#v", procName, err, err)
83 t.Fatalf("Failed to construct command for %s", procName)
85 if (c.Run() == nil) != s.success {
90 t.Fatalf("Process did not %s when it was supposed to", result)
94 func TestMain(m *testing.M) {
97 t := testProcs[procName]
99 os.Stderr.WriteString("test function did not exit\n")
109 // end of infrastructure
111 const testfile = "gocapmodetest"
112 const testfile2 = testfile + "2"
114 func CapEnterTest() {
115 _, err := os.OpenFile(path.Join(procArg, testfile), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
117 panic(fmt.Sprintf("OpenFile: %s", err))
120 err = unix.CapEnter()
122 panic(fmt.Sprintf("CapEnter: %s", err))
125 _, err = os.OpenFile(path.Join(procArg, testfile2), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
127 panic("OpenFile works!")
129 if err.(*os.PathError).Err != unix.ECAPMODE {
130 panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
135 func makeTempDir(t *testing.T) string {
136 d, err := ioutil.TempDir("", "go_openat_test")
138 t.Fatalf("TempDir failed: %s", err)
143 func removeTempDir(arg string) error {
144 err := os.RemoveAll(arg)
145 if err != nil && err.(*os.PathError).Err == unix.ENOENT {
152 testProcs["cap_enter"] = testProc{
160 func TestCapEnter(t *testing.T) {
161 if runtime.GOARCH != "amd64" {
162 t.Skipf("skipping test on %s", runtime.GOARCH)
164 ExitsCorrectly(t, "cap_enter")
168 f, err := os.Open(procArg)
173 err = unix.CapEnter()
175 panic(fmt.Sprintf("CapEnter: %s", err))
178 fxx, err := unix.Openat(int(f.Fd()), "xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
184 // The right to open BASE/xx is not ambient
185 _, err = os.OpenFile(procArg+"/xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
187 panic("OpenFile succeeded")
189 if err.(*os.PathError).Err != unix.ECAPMODE {
190 panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
193 // Can't make a new directory either
194 err = os.Mkdir(procArg+"2", 0777)
196 panic("MKdir succeeded")
198 if err.(*os.PathError).Err != unix.ECAPMODE {
199 panic(fmt.Sprintf("Mkdir failed wrong: %s %#v", err, err))
202 // Remove all caps except read and lookup.
203 r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_LOOKUP})
205 panic(fmt.Sprintf("CapRightsInit failed: %s %#v", err, err))
207 err = unix.CapRightsLimit(f.Fd(), r)
209 panic(fmt.Sprintf("CapRightsLimit failed: %s %#v", err, err))
212 // Check we can get the rights back again
213 r, err = unix.CapRightsGet(f.Fd())
215 panic(fmt.Sprintf("CapRightsGet failed: %s %#v", err, err))
217 b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP})
219 panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
222 panic(fmt.Sprintf("Unexpected rights"))
224 b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP, unix.CAP_WRITE})
226 panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
229 panic(fmt.Sprintf("Unexpected rights (2)"))
232 // Can no longer create a file
233 _, err = unix.Openat(int(f.Fd()), "xx2", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
235 panic("Openat succeeded")
237 if err != unix.ENOTCAPABLE {
238 panic(fmt.Sprintf("OpenFileAt failed wrong: %s %#v", err, err))
241 // But can read an existing one
242 _, err = unix.Openat(int(f.Fd()), "xx", os.O_RDONLY, 0666)
244 panic(fmt.Sprintf("Openat failed: %s %#v", err, err))
251 testProcs["openat"] = testProc{
259 func TestOpenat(t *testing.T) {
260 if runtime.GOARCH != "amd64" {
261 t.Skipf("skipping test on %s", runtime.GOARCH)
263 ExitsCorrectly(t, "openat")
266 func TestCapRightsSetAndClear(t *testing.T) {
267 r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT})
269 t.Fatalf("CapRightsInit failed: %s", err)
272 err = unix.CapRightsSet(r, []uint64{unix.CAP_EVENT, unix.CAP_LISTEN})
274 t.Fatalf("CapRightsSet failed: %s", err)
277 b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT, unix.CAP_EVENT, unix.CAP_LISTEN})
279 t.Fatalf("CapRightsIsSet failed: %s", err)
282 t.Fatalf("Wrong rights set")
285 err = unix.CapRightsClear(r, []uint64{unix.CAP_READ, unix.CAP_PDWAIT})
287 t.Fatalf("CapRightsClear failed: %s", err)
290 b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_WRITE, unix.CAP_EVENT, unix.CAP_LISTEN})
292 t.Fatalf("CapRightsIsSet failed: %s", err)
295 t.Fatalf("Wrong rights set")