Source file
src/syscall/exec_libc2.go
Documentation: syscall
1
2
3
4
5
6
7
8 package syscall
9
10 import (
11 "internal/abi"
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 func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
55
56
57 var (
58 r1 uintptr
59 err1 Errno
60 nextfd int
61 i int
62 )
63
64
65
66
67 fd := make([]int, len(attr.Files))
68 nextfd = len(attr.Files)
69 for i, ufd := range attr.Files {
70 if nextfd < int(ufd) {
71 nextfd = int(ufd)
72 }
73 fd[i] = int(ufd)
74 }
75 nextfd++
76
77
78
79 runtime_BeforeFork()
80 r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
81 if err1 != 0 {
82 runtime_AfterFork()
83 return 0, err1
84 }
85
86 if r1 != 0 {
87
88 runtime_AfterFork()
89 return int(r1), 0
90 }
91
92
93
94
95 if sys.Ptrace {
96 if err := ptrace(PTRACE_TRACEME, 0, 0, 0); err != nil {
97 err1 = err.(Errno)
98 goto childerror
99 }
100 }
101
102
103 if sys.Setsid {
104 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
105 if err1 != 0 {
106 goto childerror
107 }
108 }
109
110
111 if sys.Setpgid || sys.Foreground {
112
113 _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), 0, uintptr(sys.Pgid), 0)
114 if err1 != 0 {
115 goto childerror
116 }
117 }
118
119 if sys.Foreground {
120 pgrp := sys.Pgid
121 if pgrp == 0 {
122 r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
123 if err1 != 0 {
124 goto childerror
125 }
126
127 pgrp = 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