1 /* POSIX spawn interface. Linux version.
2 Copyright (C) 2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
23 #include <sys/resource.h>
25 #include <sys/param.h>
27 #include <not-cancel.h>
28 #include <local-setxid.h>
29 #include <shlib-compat.h>
30 #include <nptl/pthreadP.h>
31 #include <dl-sysdep.h>
33 #include <libc-internal.h>
34 #include "spawn_int.h"
36 /* The Linux implementation of posix_spawn{p} uses the clone syscall directly
37 with CLONE_VM and CLONE_VFORK flags and an allocated stack. The new stack
38 and start function solves most the vfork limitation (possible parent
39 clobber due stack spilling). The remaining issue are:
41 1. That no signal handlers must run in child context, to avoid corrupting
43 2. The parent must ensure child's stack freeing.
44 3. Child must synchronize with parent to enforce 2. and to possible
47 The first issue is solved by blocking all signals in child, even the
48 NPTL-internal ones (SIGCANCEL and SIGSETXID). The second and third issue
49 is done by a stack allocation in parent and a synchronization with using
50 a pipe or waitpid (in case or error). The pipe has the advantage of
51 allowing the child the communicate an exec error. */
54 /* The Unix standard contains a long explanation of the way to signal
55 an error after the fork() was successful. Since no new wait status
56 was wanted there is no way to signal an error using one of the
57 available methods. The committee chose to signal an error by a
58 normal program exit with the exit code 127. */
59 #define SPAWN_ERROR 127
61 /* We need to block both SIGCANCEL and SIGSETXID. */
63 ((__sigset_t) { .__val = {[0 ... _SIGSET_NWORDS-1 ] = -1 } })
66 # define CLONE(__fn, __stack, __stacksize, __flags, __args) \
67 __clone2 (__fn, __stack, __stacksize, __flags, __args, 0, 0, 0)
69 # define CLONE(__fn, __stack, __stacksize, __flags, __args) \
70 __clone (__fn, __stack, __flags, __args)
74 # define STACK(__stack, __stack_size) (__stack + __stack_size)
76 # define STACK(__stack, __stack_size) (__stack)
80 struct posix_spawn_args
85 int (*exec
) (const char *, char *const *, char *const *);
86 const posix_spawn_file_actions_t
*fa
;
87 const posix_spawnattr_t
*restrict attr
;
94 /* Older version requires that shell script without shebang definition
95 to be called explicitly using /bin/sh (_PATH_BSHELL). */
97 maybe_script_execute (struct posix_spawn_args
*args
)
99 if (SHLIB_COMPAT (libc
, GLIBC_2_2
, GLIBC_2_15
)
100 && (args
->xflags
& SPAWN_XFLAGS_TRY_SHELL
) && errno
== ENOEXEC
)
102 char *const *argv
= args
->argv
;
103 ptrdiff_t argc
= args
->argc
;
105 /* Construct an argument list for the shell. */
106 char *new_argv
[argc
+ 1];
107 new_argv
[0] = (char *) _PATH_BSHELL
;
108 new_argv
[1] = (char *) args
->file
;
110 memcpy (new_argv
+ 2, argv
+ 1, argc
* sizeof(char *));
114 /* Execute the shell. */
115 args
->exec (new_argv
[0], new_argv
, args
->envp
);
119 /* Function used in the clone call to setup the signals mask, posix_spawn
120 attributes, and file actions. It run on its own stack (provided by the
121 posix_spawn call). */
123 __spawni_child (void *arguments
)
125 struct posix_spawn_args
*args
= arguments
;
126 const posix_spawnattr_t
*restrict attr
= args
->attr
;
127 const posix_spawn_file_actions_t
*file_actions
= args
->fa
;
128 int p
= args
->pipe
[1];
131 close_not_cancel (args
->pipe
[0]);
133 /* The child must ensure that no signal handler are enabled because it shared
134 memory with parent, so the signal disposition must be either SIG_DFL or
135 SIG_IGN. It does by iterating over all signals and although it could
136 possibly be more optimized (by tracking which signal potentially have a
137 signal handler), it might requires system specific solutions (since the
138 sigset_t data type can be very different on different architectures). */
140 memset (&sa
, '\0', sizeof (sa
));
143 __sigprocmask (SIG_BLOCK
, 0, &hset
);
144 for (int sig
= 1; sig
< _NSIG
; ++sig
)
146 if ((attr
->__flags
& POSIX_SPAWN_SETSIGDEF
)
147 && sigismember (&attr
->__sd
, sig
))
149 sa
.sa_handler
= SIG_DFL
;
151 else if (sigismember (&hset
, sig
))
153 if (__nptl_is_internal_signal (sig
))
154 sa
.sa_handler
= SIG_IGN
;
157 __libc_sigaction (sig
, 0, &sa
);
158 if (sa
.sa_handler
== SIG_IGN
)
160 sa
.sa_handler
= SIG_DFL
;
166 __libc_sigaction (sig
, &sa
, 0);
169 #ifdef _POSIX_PRIORITY_SCHEDULING
170 /* Set the scheduling algorithm and parameters. */
171 if ((attr
->__flags
& (POSIX_SPAWN_SETSCHEDPARAM
| POSIX_SPAWN_SETSCHEDULER
))
172 == POSIX_SPAWN_SETSCHEDPARAM
)
174 if ((ret
= __sched_setparam (0, &attr
->__sp
)) == -1)
177 else if ((attr
->__flags
& POSIX_SPAWN_SETSCHEDULER
) != 0)
179 if ((ret
= __sched_setscheduler (0, attr
->__policy
, &attr
->__sp
)) == -1)
184 /* Set the process group ID. */
185 if ((attr
->__flags
& POSIX_SPAWN_SETPGROUP
) != 0
186 && (ret
= __setpgid (0, attr
->__pgrp
)) != 0)
189 /* Set the effective user and group IDs. */
190 if ((attr
->__flags
& POSIX_SPAWN_RESETIDS
) != 0
191 && ((ret
= local_seteuid (__getuid ())) != 0
192 || (ret
= local_setegid (__getgid ())) != 0))
195 /* Execute the file actions. */
196 if (file_actions
!= 0)
199 struct rlimit64 fdlimit
;
200 bool have_fdlimit
= false;
202 for (cnt
= 0; cnt
< file_actions
->__used
; ++cnt
)
204 struct __spawn_action
*action
= &file_actions
->__actions
[cnt
];
206 /* Dup the pipe fd onto an unoccupied one to avoid any file
207 operation to clobber it. */
208 if ((action
->action
.close_action
.fd
== p
)
209 || (action
->action
.open_action
.fd
== p
)
210 || (action
->action
.dup2_action
.fd
== p
))
212 if ((ret
= __dup (p
)) < 0)
221 close_not_cancel (action
->action
.close_action
.fd
)) != 0)
225 __getrlimit64 (RLIMIT_NOFILE
, &fdlimit
);
229 /* Signal errors only for file descriptors out of range. */
230 if (action
->action
.close_action
.fd
< 0
231 || action
->action
.close_action
.fd
>= fdlimit
.rlim_cur
)
238 ret
= open_not_cancel (action
->action
.open_action
.path
,
240 open_action
.oflag
| O_LARGEFILE
,
241 action
->action
.open_action
.mode
);
248 /* Make sure the desired file descriptor is used. */
249 if (ret
!= action
->action
.open_action
.fd
)
251 if ((ret
= __dup2 (new_fd
, action
->action
.open_action
.fd
))
252 != action
->action
.open_action
.fd
)
255 if ((ret
= close_not_cancel (new_fd
)) != 0)
262 if ((ret
= __dup2 (action
->action
.dup2_action
.fd
,
263 action
->action
.dup2_action
.newfd
))
264 != action
->action
.dup2_action
.newfd
)
271 /* Set the initial signal mask of the child if POSIX_SPAWN_SETSIGMASK
272 is set, otherwise restore the previous one. */
273 __sigprocmask (SIG_SETMASK
, (attr
->__flags
& POSIX_SPAWN_SETSIGMASK
)
274 ? &attr
->__ss
: &args
->oldmask
, 0);
276 args
->exec (args
->file
, args
->argv
, args
->envp
);
278 /* This is compatibility function required to enable posix_spawn run
279 script without shebang definition for older posix_spawn versions
281 maybe_script_execute (args
);
286 /* Since sizeof errno < PIPE_BUF, the write is atomic. */
289 while (write_not_cancel (p
, &ret
, sizeof ret
) < 0)
294 /* Spawn a new process executing PATH with the attributes describes in *ATTRP.
295 Before running the process perform the actions described in FILE-ACTIONS. */
297 __spawnix (pid_t
* pid
, const char *file
,
298 const posix_spawn_file_actions_t
* file_actions
,
299 const posix_spawnattr_t
* attrp
, char *const argv
[],
300 char *const envp
[], int xflags
,
301 int (*exec
) (const char *, char *const *, char *const *))
304 struct posix_spawn_args args
;
307 if (__pipe2 (args
.pipe
, O_CLOEXEC
))
310 /* To avoid imposing hard limits on posix_spawn{p} the total number of
311 arguments is first calculated to allocate a mmap to hold all possible
314 /* Linux allows at most max (0x7FFFFFFF, 1/4 stack size) arguments
315 to be used in a execve call. We limit to INT_MAX minus one due the
316 compatiblity code that may execute a shell script (maybe_script_execute)
317 where it will construct another argument list with an additional
319 ptrdiff_t limit
= INT_MAX
- 1;
320 while (argv
[argc
++] != NULL
)
327 int prot
= (PROT_READ
| PROT_WRITE
328 | ((GL (dl_stack_flags
) & PF_X
) ? PROT_EXEC
: 0));
330 /* Add a slack area for child's stack. */
331 size_t argv_size
= (argc
* sizeof (void *)) + 512;
332 size_t stack_size
= ALIGN_UP (argv_size
, GLRO(dl_pagesize
));
333 void *stack
= __mmap (NULL
, stack_size
, prot
,
334 MAP_PRIVATE
| MAP_ANONYMOUS
| MAP_STACK
, -1, 0);
335 if (__glibc_unlikely (stack
== MAP_FAILED
))
337 close_not_cancel (args
.pipe
[0]);
338 close_not_cancel (args
.pipe
[1]);
342 /* Disable asynchronous cancellation. */
343 int cs
= LIBC_CANCEL_ASYNC ();
347 args
.fa
= file_actions
;
348 args
.attr
= attrp
? attrp
: &(const posix_spawnattr_t
) { 0 };
352 args
.xflags
= xflags
;
354 __sigprocmask (SIG_BLOCK
, &SIGALL_SET
, &args
.oldmask
);
356 /* The clone flags used will create a new child that will run in the same
357 memory space (CLONE_VM) and the execution of calling thread will be
358 suspend until the child calls execve or _exit. These condition as
359 signal below either by pipe write (_exit with SPAWN_ERROR) or
361 Also since the calling thread execution will be suspend, there is not
362 need for CLONE_SETTLS. Although parent and child share the same TLS
363 namespace, there will be no concurrent access for TLS variables (errno
365 new_pid
= CLONE (__spawni_child
, STACK (stack
, stack_size
), stack_size
,
366 CLONE_VM
| CLONE_VFORK
| SIGCHLD
, &args
);
368 close_not_cancel (args
.pipe
[1]);
372 if (__read (args
.pipe
[0], &ec
, sizeof ec
) != sizeof ec
)
375 __waitpid (new_pid
, NULL
, 0);
380 __munmap (stack
, stack_size
);
382 close_not_cancel (args
.pipe
[0]);
387 __sigprocmask (SIG_SETMASK
, &args
.oldmask
, 0);
389 LIBC_CANCEL_RESET (cs
);
394 /* Spawn a new process executing PATH with the attributes describes in *ATTRP.
395 Before running the process perform the actions described in FILE-ACTIONS. */
397 __spawni (pid_t
* pid
, const char *file
,
398 const posix_spawn_file_actions_t
* acts
,
399 const posix_spawnattr_t
* attrp
, char *const argv
[],
400 char *const envp
[], int xflags
)
402 return __spawnix (pid
, file
, acts
, attrp
, argv
, envp
, xflags
,
403 xflags
& SPAWN_XFLAGS_USE_PATH
? __execvpe
: __execve
);