| // 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") |
| } |