// Program posix is a test case to confirm that Go is capable of // exhibiting posix semantics for system calls. // // This code is a template for two programs: posix.go and posix-cgo.go // which are built by the Makefile to using sed. package main import ( "fmt" "io/ioutil" "log" "os" "strings" "syscall" ) // main_here func dumpStatus(testCase string, err error, filter, expect string) bool { fmt.Printf("%s [%v]:\n", testCase, err) var failed bool pid := syscall.Getpid() fs, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/task", pid)) if err != nil { log.Fatal(err) } for _, f := range fs { tf := fmt.Sprintf("/proc/%s/status", f.Name()) d, err := ioutil.ReadFile(tf) if err != nil { fmt.Println(tf, err) failed = true continue } lines := strings.Split(string(d), "\n") for _, line := range lines { if strings.HasPrefix(line, filter) { fails := line != expect failure := "" if fails { failed = fails failure = " (bad)" } fmt.Printf("%s %s%s\n", tf, line, failure) break } } } return failed } func ptest() { var err error var bad bool // egid setting bad = bad || dumpStatus("initial state", nil, "Gid:", "Gid:\t0\t0\t0\t0") err = syscall.Setegid(1001) bad = bad || dumpStatus("setegid(1001) state", err, "Gid:", "Gid:\t0\t1001\t0\t1001") err = syscall.Setegid(1002) bad = bad || dumpStatus("setegid(1002) state", err, "Gid:", "Gid:\t0\t1002\t0\t1002") err = syscall.Setegid(0) bad = bad || dumpStatus("setegid(0) state", err, "Gid:", "Gid:\t0\t0\t0\t0") // euid setting (no way back from this one) bad = bad || dumpStatus("initial euid", nil, "Uid:", "Uid:\t0\t0\t0\t0") err = syscall.Seteuid(1) bad = bad || dumpStatus("seteuid(1)", err, "Uid:", "Uid:\t0\t1\t0\t1") err = syscall.Seteuid(0) bad = bad || dumpStatus("seteuid(0)", err, "Uid:", "Uid:\t0\t0\t0\t0") // gid setting bad = bad || dumpStatus("initial state", nil, "Gid:", "Gid:\t0\t0\t0\t0") err = syscall.Setgid(1001) bad = bad || dumpStatus("setgid(1001) state", err, "Gid:", "Gid:\t1001\t1001\t1001\t1001") err = syscall.Setgid(1002) bad = bad || dumpStatus("setgid(1002) state", err, "Gid:", "Gid:\t1002\t1002\t1002\t1002") err = syscall.Setgid(0) bad = bad || dumpStatus("setgid(0) state", err, "Gid:", "Gid:\t0\t0\t0\t0") // groups setting bad = bad || dumpStatus("initial groups", nil, "Groups:", "Groups:\t0 ") err = syscall.Setgroups([]int{0, 1, 2, 3}) bad = bad || dumpStatus("setgroups(0,1,2,3)", err, "Groups:", "Groups:\t0 1 2 3 ") err = syscall.Setgroups([]int{3, 2, 1}) bad = bad || dumpStatus("setgroups(2,3,1)", err, "Groups:", "Groups:\t1 2 3 ") err = syscall.Setgroups(nil) bad = bad || dumpStatus("setgroups(nil)", err, "Groups:", "Groups:\t ") err = syscall.Setgroups([]int{0}) bad = bad || dumpStatus("setgroups(0)", err, "Groups:", "Groups:\t0 ") // regid setting bad = bad || dumpStatus("initial state", nil, "Gid:", "Gid:\t0\t0\t0\t0") err = syscall.Setregid(1001, 0) bad = bad || dumpStatus("setregid(1001) state", err, "Gid:", "Gid:\t1001\t0\t0\t0") err = syscall.Setregid(0, 1002) bad = bad || dumpStatus("setregid(1002) state", err, "Gid:", "Gid:\t0\t1002\t1002\t1002") err = syscall.Setregid(0, 0) bad = bad || dumpStatus("setregid(0) state", err, "Gid:", "Gid:\t0\t0\t0\t0") // reuid setting bad = bad || dumpStatus("initial state", nil, "Uid:", "Uid:\t0\t0\t0\t0") err = syscall.Setreuid(1, 0) bad = bad || dumpStatus("setreuid(1,0) state", err, "Uid:", "Uid:\t1\t0\t0\t0") err = syscall.Setreuid(0, 2) bad = bad || dumpStatus("setreuid(0,2) state", err, "Uid:", "Uid:\t0\t2\t2\t2") err = syscall.Setreuid(0, 0) bad = bad || dumpStatus("setreuid(0) state", err, "Uid:", "Uid:\t0\t0\t0\t0") // resgid setting bad = bad || dumpStatus("initial state", nil, "Gid:", "Gid:\t0\t0\t0\t0") err = syscall.Setresgid(1, 0, 2) bad = bad || dumpStatus("setresgid(1,0,2) state", err, "Gid:", "Gid:\t1\t0\t2\t0") err = syscall.Setresgid(0, 2, 1) bad = bad || dumpStatus("setresgid(0,2,1) state", err, "Gid:", "Gid:\t0\t2\t1\t2") err = syscall.Setresgid(0, 0, 0) bad = bad || dumpStatus("setresgid(0) state", err, "Gid:", "Gid:\t0\t0\t0\t0") // resuid setting bad = bad || dumpStatus("initial state", nil, "Uid:", "Uid:\t0\t0\t0\t0") err = syscall.Setresuid(1, 0, 2) bad = bad || dumpStatus("setresuid(1,0,2) state", err, "Uid:", "Uid:\t1\t0\t2\t0") err = syscall.Setresuid(0, 2, 1) bad = bad || dumpStatus("setresuid(0,2,1) state", err, "Uid:", "Uid:\t0\t2\t1\t2") err = syscall.Setresuid(0, 0, 0) bad = bad || dumpStatus("setresuid(0) state", err, "Uid:", "Uid:\t0\t0\t0\t0") // uid setting (no way back from this one) bad = bad || dumpStatus("initial uid", nil, "Uid:", "Uid:\t0\t0\t0\t0") err = syscall.Setuid(1) bad = bad || dumpStatus("setuid(1)", err, "Uid:", "Uid:\t1\t1\t1\t1") err = syscall.Setuid(0) bad = bad || dumpStatus("setuid(0)", err, "Uid:", "Uid:\t1\t1\t1\t1") if bad { log.Print("TEST FAILED") os.Exit(1) } log.Print("TEST PASSED") }