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