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 err error
63 pgrp _C_int
64 cred *Credential
65 ngroups, groups uintptr
66 )
67
68 rlim := origRlimitNofile.Load()
69
70
71
72
73 fd := make([]int, len(attr.Files))
74 nextfd = len(attr.Files)
75 for i, ufd := range attr.Files {
76 if nextfd < int(ufd) {
77 nextfd = int(ufd)
78 }
79 fd[i] = int(ufd)
80 }
81 nextfd++
82
83
84
85 runtime_BeforeFork()
86 r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
87 if err1 != 0 {
88 runtime_AfterFork()
89 return 0, err1
90 }
91
92 if r1 != 0 {
93
94 runtime_AfterFork()
95 return int(r1), 0
96 }
97
98
99
100
101 if sys.Ptrace {
102 if err = ptrace(PTRACE_TRACEME, 0, 0, 0); err != nil {
103 err1 = err.(Errno)
104 goto childerror
105 }
106 }
107
108
109 if sys.Setsid {
110 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
111 if err1 != 0 {
112 goto childerror
113 }
114 }
115
116
117 if sys.Setpgid || sys.Foreground {
118
119 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), 0, uintptr(sys.Pgid), 0)
120 if err1 != 0 {
121 goto childerror
122 }
123 }
124
125 if sys.Foreground {
126
127
128 pgrp = _C_int(sys.Pgid)
129 if pgrp == 0 {
130 r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
131 if err1 != 0 {
132 goto childerror
133 }
134 pgrp = _C_int(r1)
135 }
136
137
138 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSPGRP), uintptr(unsafe.Pointer(&pgrp)))
139 if err1 != 0 {
140 goto childerror
141 }
142 }
143
144
145
146 runtime_AfterForkInChild()
147
148
149 if chroot != nil {
150 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(chroot)), 0, 0)
151 if err1 != 0 {
152 goto childerror
153 }
154 }
155
156
157 if cred = sys.Credential; cred != nil {
158 ngroups = uintptr(len(cred.Groups))
159 groups = uintptr(0)
160 if ngroups > 0 {
161 groups = uintptr(unsafe.Pointer(&cred.Groups[0]))
162 }
163 if !cred.NoSetGroups {
164 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), ngroups, groups, 0)
165 if err1 != 0 {
166 goto childerror
167 }
168 }
169 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(cred.Gid), 0, 0)
170 if err1 != 0 {
171 goto childerror
172 }
173 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(cred.Uid), 0, 0)
174 if err1 != 0 {
175 goto childerror
176 }
177 }
178
179
180 if dir != nil {
181 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(dir)), 0, 0)
182 if err1 != 0 {
183 goto childerror
184 }
185 }
186
187
188
189 if pipe < nextfd {
190 if runtime.GOOS == "openbsd" {
191 _, _, err1 = rawSyscall(dupTrampoline, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
192 } else {
193 _, _, err1 = rawSyscall(dupTrampoline, uintptr(pipe), uintptr(nextfd), 0)
194 if err1 != 0 {
195 goto childerror
196 }
197 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
198 }
199 if err1 != 0 {
200 goto childerror
201 }
202 pipe = nextfd
203 nextfd++
204 }
205 for i = 0; i < len(fd); i++ {
206 if fd[i] >= 0 && fd[i] < i {
207 if nextfd == pipe {
208 nextfd++
209 }
210 if runtime.GOOS == "openbsd" {
211 _, _, err1 = rawSyscall(dupTrampoline, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
212 } else {
213 _, _, err1 = rawSyscall(dupTrampoline, uintptr(fd[i]), uintptr(nextfd), 0)
214 if err1 != 0 {
215 goto childerror
216 }
217 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
218 }
219 if err1 != 0 {
220 goto childerror
221 }
222 fd[i] = nextfd
223 nextfd++
224 }
225 }
226
227
228 for i = 0; i < len(fd); i++ {
229 if fd[i] == -1 {
230 rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
231 continue
232 }
233 if fd[i] == i {
234
235
236 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd[i]), F_SETFD, 0)
237 if err1 != 0 {
238 goto childerror
239 }
240 continue
241 }
242
243
244 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(fd[i]), uintptr(i), 0)
245 if err1 != 0 {
246 goto childerror
247 }
248 }
249
250
251
252
253
254 for i = len(fd); i < 3; i++ {
255 rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
256 }
257
258
259 if sys.Noctty {
260 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), 0, uintptr(TIOCNOTTY), 0)
261 if err1 != 0 {
262 goto childerror
263 }
264 }
265
266
267 if sys.Setctty {
268 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
269 if err1 != 0 {
270 goto childerror
271 }
272 }
273
274
275 if rlim != nil {
276 rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(RLIMIT_NOFILE), uintptr(unsafe.Pointer(rlim)), 0)
277 }
278
279
280 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_execve_trampoline),
281 uintptr(unsafe.Pointer(argv0)),
282 uintptr(unsafe.Pointer(&argv[0])),
283 uintptr(unsafe.Pointer(&envv[0])))
284
285 childerror:
286
287 rawSyscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
288 for {
289 rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), 253, 0, 0)
290 }
291 }
292
293
294 func forkAndExecFailureCleanup(attr *ProcAttr, sys *SysProcAttr) {
295
296 }
297
View as plain text