syscall_freebsd_test.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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.
  4. // +build freebsd
  5. package unix_test
  6. import (
  7. "flag"
  8. "fmt"
  9. "io/ioutil"
  10. "os"
  11. "os/exec"
  12. "path"
  13. "path/filepath"
  14. "testing"
  15. "golang.org/x/sys/unix"
  16. )
  17. func TestSysctlUint64(t *testing.T) {
  18. _, err := unix.SysctlUint64("security.mac.labeled")
  19. if err != nil {
  20. t.Fatal(err)
  21. }
  22. }
  23. // FIXME: Infrastructure for launching tests in subprocesses stolen from openbsd_test.go - refactor?
  24. // testCmd generates a proper command that, when executed, runs the test
  25. // corresponding to the given key.
  26. type testProc struct {
  27. fn func() // should always exit instead of returning
  28. arg func(t *testing.T) string // generate argument for test
  29. cleanup func(arg string) error // for instance, delete coredumps from testing pledge
  30. success bool // whether zero-exit means success or failure
  31. }
  32. var (
  33. testProcs = map[string]testProc{}
  34. procName = ""
  35. procArg = ""
  36. )
  37. const (
  38. optName = "sys-unix-internal-procname"
  39. optArg = "sys-unix-internal-arg"
  40. )
  41. func init() {
  42. flag.StringVar(&procName, optName, "", "internal use only")
  43. flag.StringVar(&procArg, optArg, "", "internal use only")
  44. }
  45. func testCmd(procName string, procArg string) (*exec.Cmd, error) {
  46. exe, err := filepath.Abs(os.Args[0])
  47. if err != nil {
  48. return nil, err
  49. }
  50. cmd := exec.Command(exe, "-"+optName+"="+procName, "-"+optArg+"="+procArg)
  51. cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
  52. return cmd, nil
  53. }
  54. // ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
  55. // a testProc with a key.
  56. func ExitsCorrectly(t *testing.T, procName string) {
  57. s := testProcs[procName]
  58. arg := "-"
  59. if s.arg != nil {
  60. arg = s.arg(t)
  61. }
  62. c, err := testCmd(procName, arg)
  63. defer func(arg string) {
  64. if err := s.cleanup(arg); err != nil {
  65. t.Fatalf("Failed to run cleanup for %s %s %#v", procName, err, err)
  66. }
  67. }(arg)
  68. if err != nil {
  69. t.Fatalf("Failed to construct command for %s", procName)
  70. }
  71. if (c.Run() == nil) != s.success {
  72. result := "succeed"
  73. if !s.success {
  74. result = "fail"
  75. }
  76. t.Fatalf("Process did not %s when it was supposed to", result)
  77. }
  78. }
  79. func TestMain(m *testing.M) {
  80. flag.Parse()
  81. if procName != "" {
  82. t := testProcs[procName]
  83. t.fn()
  84. os.Stderr.WriteString("test function did not exit\n")
  85. if t.success {
  86. os.Exit(1)
  87. } else {
  88. os.Exit(0)
  89. }
  90. }
  91. os.Exit(m.Run())
  92. }
  93. // end of infrastructure
  94. const testfile = "gocapmodetest"
  95. const testfile2 = testfile + "2"
  96. func CapEnterTest() {
  97. _, err := os.OpenFile(path.Join(procArg, testfile), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
  98. if err != nil {
  99. panic(fmt.Sprintf("OpenFile: %s", err))
  100. }
  101. err = unix.CapEnter()
  102. if err != nil {
  103. panic(fmt.Sprintf("CapEnter: %s", err))
  104. }
  105. _, err = os.OpenFile(path.Join(procArg, testfile2), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
  106. if err == nil {
  107. panic("OpenFile works!")
  108. }
  109. if err.(*os.PathError).Err != unix.ECAPMODE {
  110. panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
  111. }
  112. os.Exit(0)
  113. }
  114. func makeTempDir(t *testing.T) string {
  115. d, err := ioutil.TempDir("", "go_openat_test")
  116. if err != nil {
  117. t.Fatalf("TempDir failed: %s", err)
  118. }
  119. return d
  120. }
  121. func removeTempDir(arg string) error {
  122. err := os.RemoveAll(arg)
  123. if err != nil && err.(*os.PathError).Err == unix.ENOENT {
  124. return nil
  125. }
  126. return err
  127. }
  128. func init() {
  129. testProcs["cap_enter"] = testProc{
  130. CapEnterTest,
  131. makeTempDir,
  132. removeTempDir,
  133. true,
  134. }
  135. }
  136. func TestCapEnter(t *testing.T) {
  137. ExitsCorrectly(t, "cap_enter")
  138. }
  139. func OpenatTest() {
  140. f, err := os.Open(procArg)
  141. if err != nil {
  142. panic(err)
  143. }
  144. err = unix.CapEnter()
  145. if err != nil {
  146. panic(fmt.Sprintf("CapEnter: %s", err))
  147. }
  148. fxx, err := unix.Openat(int(f.Fd()), "xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
  149. if err != nil {
  150. panic(err)
  151. }
  152. unix.Close(fxx)
  153. // The right to open BASE/xx is not ambient
  154. _, err = os.OpenFile(procArg+"/xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
  155. if err == nil {
  156. panic("OpenFile succeeded")
  157. }
  158. if err.(*os.PathError).Err != unix.ECAPMODE {
  159. panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
  160. }
  161. // Can't make a new directory either
  162. err = os.Mkdir(procArg+"2", 0777)
  163. if err == nil {
  164. panic("MKdir succeeded")
  165. }
  166. if err.(*os.PathError).Err != unix.ECAPMODE {
  167. panic(fmt.Sprintf("Mkdir failed wrong: %s %#v", err, err))
  168. }
  169. // Remove all caps except read and lookup.
  170. r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_LOOKUP})
  171. if err != nil {
  172. panic(fmt.Sprintf("CapRightsInit failed: %s %#v", err, err))
  173. }
  174. err = unix.CapRightsLimit(f.Fd(), r)
  175. if err != nil {
  176. panic(fmt.Sprintf("CapRightsLimit failed: %s %#v", err, err))
  177. }
  178. // Check we can get the rights back again
  179. r, err = unix.CapRightsGet(f.Fd())
  180. if err != nil {
  181. panic(fmt.Sprintf("CapRightsGet failed: %s %#v", err, err))
  182. }
  183. b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP})
  184. if err != nil {
  185. panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
  186. }
  187. if !b {
  188. panic(fmt.Sprintf("Unexpected rights"))
  189. }
  190. b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP, unix.CAP_WRITE})
  191. if err != nil {
  192. panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
  193. }
  194. if b {
  195. panic(fmt.Sprintf("Unexpected rights (2)"))
  196. }
  197. // Can no longer create a file
  198. _, err = unix.Openat(int(f.Fd()), "xx2", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
  199. if err == nil {
  200. panic("Openat succeeded")
  201. }
  202. if err != unix.ENOTCAPABLE {
  203. panic(fmt.Sprintf("OpenFileAt failed wrong: %s %#v", err, err))
  204. }
  205. // But can read an existing one
  206. _, err = unix.Openat(int(f.Fd()), "xx", os.O_RDONLY, 0666)
  207. if err != nil {
  208. panic(fmt.Sprintf("Openat failed: %s %#v", err, err))
  209. }
  210. os.Exit(0)
  211. }
  212. func init() {
  213. testProcs["openat"] = testProc{
  214. OpenatTest,
  215. makeTempDir,
  216. removeTempDir,
  217. true,
  218. }
  219. }
  220. func TestOpenat(t *testing.T) {
  221. ExitsCorrectly(t, "openat")
  222. }
  223. func TestCapRightsSetAndClear(t *testing.T) {
  224. r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT})
  225. if err != nil {
  226. t.Fatalf("CapRightsInit failed: %s", err)
  227. }
  228. err = unix.CapRightsSet(r, []uint64{unix.CAP_EVENT, unix.CAP_LISTEN})
  229. if err != nil {
  230. t.Fatalf("CapRightsSet failed: %s", err)
  231. }
  232. b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT, unix.CAP_EVENT, unix.CAP_LISTEN})
  233. if err != nil {
  234. t.Fatalf("CapRightsIsSet failed: %s", err)
  235. }
  236. if !b {
  237. t.Fatalf("Wrong rights set")
  238. }
  239. err = unix.CapRightsClear(r, []uint64{unix.CAP_READ, unix.CAP_PDWAIT})
  240. if err != nil {
  241. t.Fatalf("CapRightsClear failed: %s", err)
  242. }
  243. b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_WRITE, unix.CAP_EVENT, unix.CAP_LISTEN})
  244. if err != nil {
  245. t.Fatalf("CapRightsIsSet failed: %s", err)
  246. }
  247. if !b {
  248. t.Fatalf("Wrong rights set")
  249. }
  250. }