Source file
src/syscall/exec_libc2.go
1
2
3
4
5
6
7 package syscall
8
9 import (
10 "internal/abi"
11 "runtime"
12 "unsafe"
13 )
14
15 type SysProcAttr struct {
16 Chroot string
17 Credential *Credential
18 Ptrace bool
19 Setsid bool
20
21
22 Setpgid bool
23
24
25
26
27 Setctty bool
28 Noctty bool
29 Ctty int
30
31
32
33
34
35 Foreground bool
36 Pgid int
37 }
38
39
40 func runtime_BeforeFork()
41 func runtime_AfterFork()
42 func runtime_AfterForkInChild()
43
44
45
46
47
48
49
50
51
52
53
54
55 func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err1 Errno) {
56
57
58 var (
59 r1 uintptr
60 nextfd int
61 i int
62 pgrp _C_int
63 cred *Credential
64 ngroups, groups uintptr
65 )
66
67 rlim := origRlimitNofile.Load()
68
69
70
71
72 fd := make([]int, len(attr.Files))
73 nextfd = len(attr.Files)
74 for i, ufd := range attr.Files {
75 if nextfd < int(ufd) {
76 nextfd = int(ufd)
77 }
78 fd[i] = int(ufd)
79 }
80 nextfd++
81
82
83
84 runtime_BeforeFork()
85 r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
86 if err1 != 0 {
87 runtime_AfterFork()
88 return 0, err1
89 }
90
91 if r1 != 0 {
92
93 runtime_AfterFork()
94 return int(r1), 0
95 }
96
97
98
99
100 if sys.Ptrace {
101 if runtime.GOOS == "ios" {
102 err1 = ENOSYS
103 goto childerror
104 }
105 _, _, err1 = rawSyscall6(abi.FuncPCABI0(libc_ptrace_trampoline), PTRACE_TRACEME, 0, 0, 0, 0, 0)
106 if err1 != 0 {
107 goto childerror
108 }
109 }
110
111
112 if sys.Setsid {
113 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
114 if err1 != 0 {
115 goto childerror
116 }
117 }
118
119
120 if sys.Setpgid || sys.Foreground {
121
122 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), 0, uintptr(sys.Pgid), 0)
123 if err1 != 0 {
124 goto childerror
125 }
126 }
127
128 if sys.Foreground {
129
130
131 pgrp = _C_int(sys.Pgid)
132 if pgrp == 0 {
133 r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
134 if err1 != 0 {
135 goto childerror
136 }
137 pgrp = _C_int(r1)
138 }
139
140
141 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSPGRP), uintptr(unsafe.Pointer(&pgrp)))
142 if err1 != 0 {
143 goto childerror
144 }
145 }
146
147
148
149 runtime_AfterForkInChild()
150
151
152 if chroot != nil {
153 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(chroot)), 0, 0)
154 if err1 != 0 {
155 goto childerror
156 }
157 }
158
159
160 if cred = sys.Credential; cred != nil {
161 ngroups = uintptr(len(cred.Groups))
162 groups = uintptr(0)
163 if ngroups > 0 {
164 groups = uintptr(unsafe.Pointer(&cred.Groups[0]))
165 }
166 if !cred.NoSetGroups {
167 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), ngroups, groups, 0)
168 if err1 != 0 {
169 goto childerror
170 }
171 }
172 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(cred.Gid), 0, 0)
173 if err1 != 0 {
174 goto childerror
175 }
176 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(cred.Uid), 0, 0)
177 if err1 != 0 {
178 goto childerror
179 }
180 }
181
182
183 if dir != nil {
184 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(dir)), 0, 0)
185 if err1 != 0 {
186 goto childerror
187 }
188 }
189
190
191
192 if pipe < nextfd {
193 if runtime.GOOS == "openbsd" {
194 _, _, err1 = rawSyscall(dupTrampoline, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
195 } else {
196 _, _, err1 = rawSyscall(dupTrampoline, uintptr(pipe), uintptr(nextfd), 0)
197 if err1 != 0 {
198 goto childerror
199 }
200 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
201 }
202 if err1 != 0 {
203 goto childerror
204 }
205 pipe = nextfd
206 nextfd++
207 }
208 for i = 0; i < len(fd); i++ {
209 if fd[i] >= 0 && fd[i] < i {
210 if nextfd == pipe {
211 nextfd++
212 }
213 if runtime.GOOS == "openbsd" {
214 _, _, err1 = rawSyscall(dupTrampoline, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
215 } else {
216 _, _, err1 = rawSyscall(dupTrampoline, uintptr(fd[i]), uintptr(nextfd), 0)
217 if err1 != 0 {
218 goto childerror
219 }
220 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
221 }
222 if err1 != 0 {
223 goto childerror
224 }
225 fd[i] = nextfd
226 nextfd++
227 }
228 }
229
230
231 for i = 0; i < len(fd); i++ {
232 if fd[i] == -1 {
233 rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
234 continue
235 }
236 if fd[i] == i {
237
238
239 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd[i]), F_SETFD, 0)
240 if err1 != 0 {
241 goto childerror
242 }
243 continue
244 }
245
246
247 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(fd[i]), uintptr(i), 0)
248 if err1 != 0 {
249 goto childerror
250 }
251 }
252
253
254
255
256
257 for i = len(fd); i < 3; i++ {
258 rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
259 }
260
261
262 if sys.Noctty {
263 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), 0, uintptr(TIOCNOTTY), 0)
264 if err1 != 0 {
265 goto childerror
266 }
267 }
268
269
270 if sys.Setctty {
271 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
272 if err1 != 0 {
273 goto childerror
274 }
275 }
276
277
278 if rlim != nil {
279 rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(RLIMIT_NOFILE), uintptr(unsafe.Pointer(rlim)), 0)
280 }
281
282
283 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_execve_trampoline),
284 uintptr(unsafe.Pointer(argv0)),
285 uintptr(unsafe.Pointer(&argv[0])),
286 uintptr(unsafe.Pointer(&envv[0])))
287
288 childerror:
289
290 rawSyscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
291 for {
292 rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), 253, 0, 0)
293 }
294 }
295
296
297 func forkAndExecFailureCleanup(attr *ProcAttr, sys *SysProcAttr) {
298
299 }
300
View as plain text