exec_unix.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // Copyright 2009 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 darwin dragonfly freebsd linux netbsd openbsd solaris
  5. // Fork, exec, wait, etc.
  6. package unix
  7. import (
  8. "runtime"
  9. "sync"
  10. "unsafe"
  11. )
  12. // Lock synchronizing creation of new file descriptors with fork.
  13. //
  14. // We want the child in a fork/exec sequence to inherit only the
  15. // file descriptors we intend. To do that, we mark all file
  16. // descriptors close-on-exec and then, in the child, explicitly
  17. // unmark the ones we want the exec'ed program to keep.
  18. // Unix doesn't make this easy: there is, in general, no way to
  19. // allocate a new file descriptor close-on-exec. Instead you
  20. // have to allocate the descriptor and then mark it close-on-exec.
  21. // If a fork happens between those two events, the child's exec
  22. // will inherit an unwanted file descriptor.
  23. //
  24. // This lock solves that race: the create new fd/mark close-on-exec
  25. // operation is done holding ForkLock for reading, and the fork itself
  26. // is done holding ForkLock for writing. At least, that's the idea.
  27. // There are some complications.
  28. //
  29. // Some system calls that create new file descriptors can block
  30. // for arbitrarily long times: open on a hung NFS server or named
  31. // pipe, accept on a socket, and so on. We can't reasonably grab
  32. // the lock across those operations.
  33. //
  34. // It is worse to inherit some file descriptors than others.
  35. // If a non-malicious child accidentally inherits an open ordinary file,
  36. // that's not a big deal. On the other hand, if a long-lived child
  37. // accidentally inherits the write end of a pipe, then the reader
  38. // of that pipe will not see EOF until that child exits, potentially
  39. // causing the parent program to hang. This is a common problem
  40. // in threaded C programs that use popen.
  41. //
  42. // Luckily, the file descriptors that are most important not to
  43. // inherit are not the ones that can take an arbitrarily long time
  44. // to create: pipe returns instantly, and the net package uses
  45. // non-blocking I/O to accept on a listening socket.
  46. // The rules for which file descriptor-creating operations use the
  47. // ForkLock are as follows:
  48. //
  49. // 1) Pipe. Does not block. Use the ForkLock.
  50. // 2) Socket. Does not block. Use the ForkLock.
  51. // 3) Accept. If using non-blocking mode, use the ForkLock.
  52. // Otherwise, live with the race.
  53. // 4) Open. Can block. Use O_CLOEXEC if available (Linux).
  54. // Otherwise, live with the race.
  55. // 5) Dup. Does not block. Use the ForkLock.
  56. // On Linux, could use fcntl F_DUPFD_CLOEXEC
  57. // instead of the ForkLock, but only for dup(fd, -1).
  58. var ForkLock sync.RWMutex
  59. // StringSlicePtr is deprecated. Use SlicePtrFromStrings instead.
  60. // If any string contains a NUL byte this function panics instead
  61. // of returning an error.
  62. func StringSlicePtr(ss []string) []*byte {
  63. bb := make([]*byte, len(ss)+1)
  64. for i := 0; i < len(ss); i++ {
  65. bb[i] = StringBytePtr(ss[i])
  66. }
  67. bb[len(ss)] = nil
  68. return bb
  69. }
  70. // SlicePtrFromStrings converts a slice of strings to a slice of
  71. // pointers to NUL-terminated byte slices. If any string contains
  72. // a NUL byte, it returns (nil, EINVAL).
  73. func SlicePtrFromStrings(ss []string) ([]*byte, error) {
  74. var err error
  75. bb := make([]*byte, len(ss)+1)
  76. for i := 0; i < len(ss); i++ {
  77. bb[i], err = BytePtrFromString(ss[i])
  78. if err != nil {
  79. return nil, err
  80. }
  81. }
  82. bb[len(ss)] = nil
  83. return bb, nil
  84. }
  85. func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
  86. func SetNonblock(fd int, nonblocking bool) (err error) {
  87. flag, err := fcntl(fd, F_GETFL, 0)
  88. if err != nil {
  89. return err
  90. }
  91. if nonblocking {
  92. flag |= O_NONBLOCK
  93. } else {
  94. flag &= ^O_NONBLOCK
  95. }
  96. _, err = fcntl(fd, F_SETFL, flag)
  97. return err
  98. }
  99. // Credential holds user and group identities to be assumed
  100. // by a child process started by StartProcess.
  101. type Credential struct {
  102. Uid uint32 // User ID.
  103. Gid uint32 // Group ID.
  104. Groups []uint32 // Supplementary group IDs.
  105. }
  106. // ProcAttr holds attributes that will be applied to a new process started
  107. // by StartProcess.
  108. type ProcAttr struct {
  109. Dir string // Current working directory.
  110. Env []string // Environment.
  111. Files []uintptr // File descriptors.
  112. Sys *SysProcAttr
  113. }
  114. var zeroProcAttr ProcAttr
  115. var zeroSysProcAttr SysProcAttr
  116. func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
  117. var p [2]int
  118. var n int
  119. var err1 Errno
  120. var wstatus WaitStatus
  121. if attr == nil {
  122. attr = &zeroProcAttr
  123. }
  124. sys := attr.Sys
  125. if sys == nil {
  126. sys = &zeroSysProcAttr
  127. }
  128. p[0] = -1
  129. p[1] = -1
  130. // Convert args to C form.
  131. argv0p, err := BytePtrFromString(argv0)
  132. if err != nil {
  133. return 0, err
  134. }
  135. argvp, err := SlicePtrFromStrings(argv)
  136. if err != nil {
  137. return 0, err
  138. }
  139. envvp, err := SlicePtrFromStrings(attr.Env)
  140. if err != nil {
  141. return 0, err
  142. }
  143. if (runtime.GOOS == "freebsd" || runtime.GOOS == "dragonfly") && len(argv[0]) > len(argv0) {
  144. argvp[0] = argv0p
  145. }
  146. var chroot *byte
  147. if sys.Chroot != "" {
  148. chroot, err = BytePtrFromString(sys.Chroot)
  149. if err != nil {
  150. return 0, err
  151. }
  152. }
  153. var dir *byte
  154. if attr.Dir != "" {
  155. dir, err = BytePtrFromString(attr.Dir)
  156. if err != nil {
  157. return 0, err
  158. }
  159. }
  160. // Acquire the fork lock so that no other threads
  161. // create new fds that are not yet close-on-exec
  162. // before we fork.
  163. ForkLock.Lock()
  164. // Allocate child status pipe close on exec.
  165. if err = forkExecPipe(p[:]); err != nil {
  166. goto error
  167. }
  168. // Kick off child.
  169. pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
  170. if err1 != 0 {
  171. err = Errno(err1)
  172. goto error
  173. }
  174. ForkLock.Unlock()
  175. // Read child error status from pipe.
  176. Close(p[1])
  177. n, err = readlen(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
  178. Close(p[0])
  179. if err != nil || n != 0 {
  180. if n == int(unsafe.Sizeof(err1)) {
  181. err = Errno(err1)
  182. }
  183. if err == nil {
  184. err = EPIPE
  185. }
  186. // Child failed; wait for it to exit, to make sure
  187. // the zombies don't accumulate.
  188. _, err1 := Wait4(pid, &wstatus, 0, nil)
  189. for err1 == EINTR {
  190. _, err1 = Wait4(pid, &wstatus, 0, nil)
  191. }
  192. return 0, err
  193. }
  194. // Read got EOF, so pipe closed on exec, so exec succeeded.
  195. return pid, nil
  196. error:
  197. if p[0] >= 0 {
  198. Close(p[0])
  199. Close(p[1])
  200. }
  201. ForkLock.Unlock()
  202. return 0, err
  203. }
  204. // Combination of fork and exec, careful to be thread safe.
  205. func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
  206. return forkExec(argv0, argv, attr)
  207. }
  208. // StartProcess wraps ForkExec for package os.
  209. func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
  210. pid, err = forkExec(argv0, argv, attr)
  211. return pid, 0, err
  212. }
  213. // Ordinary exec.
  214. func Exec(argv0 string, argv []string, envv []string) (err error) {
  215. argv0p, err := BytePtrFromString(argv0)
  216. if err != nil {
  217. return err
  218. }
  219. argvp, err := SlicePtrFromStrings(argv)
  220. if err != nil {
  221. return err
  222. }
  223. envvp, err := SlicePtrFromStrings(envv)
  224. if err != nil {
  225. return err
  226. }
  227. _, _, err1 := RawSyscall(SYS_EXECVE,
  228. uintptr(unsafe.Pointer(argv0p)),
  229. uintptr(unsafe.Pointer(&argvp[0])),
  230. uintptr(unsafe.Pointer(&envvp[0])))
  231. return Errno(err1)
  232. }