posix: Fix posix_spawn invalid memory access
[glibc.git] / sysdeps / unix / sysv / linux / spawni.c
blobcb80cea00fcd958c743dd2555a318c48cabff62d
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/>. */
19 #include <spawn.h>
20 #include <fcntl.h>
21 #include <paths.h>
22 #include <string.h>
23 #include <sys/resource.h>
24 #include <sys/wait.h>
25 #include <sys/param.h>
26 #include <sys/mman.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>
32 #include <ldsodefs.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
42 parent's state.
43 2. The parent must ensure child's stack freeing.
44 3. Child must synchronize with parent to enforce 2. and to possible
45 return execv issues.
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. */
62 #define SIGALL_SET \
63 ((__sigset_t) { .__val = {[0 ... _SIGSET_NWORDS-1 ] = -1 } })
65 #ifdef __ia64__
66 # define CLONE(__fn, __stack, __stacksize, __flags, __args) \
67 __clone2 (__fn, __stack, __stacksize, __flags, __args, 0, 0, 0)
68 #else
69 # define CLONE(__fn, __stack, __stacksize, __flags, __args) \
70 __clone (__fn, __stack, __flags, __args)
71 #endif
73 #if _STACK_GROWS_DOWN
74 # define STACK(__stack, __stack_size) (__stack + __stack_size)
75 #elif _STACK_GROWS_UP
76 # define STACK(__stack, __stack_size) (__stack)
77 #endif
80 struct posix_spawn_args
82 int pipe[2];
83 sigset_t oldmask;
84 const char *file;
85 int (*exec) (const char *, char *const *, char *const *);
86 const posix_spawn_file_actions_t *fa;
87 const posix_spawnattr_t *restrict attr;
88 char *const *argv;
89 ptrdiff_t argc;
90 char *const *envp;
91 int xflags;
94 /* Older version requires that shell script without shebang definition
95 to be called explicitly using /bin/sh (_PATH_BSHELL). */
96 static void
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;
109 if (argc > 1)
110 memcpy (new_argv + 2, argv + 1, argc * sizeof(char *));
111 else
112 new_argv[2] = NULL;
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). */
122 static int
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];
129 int ret;
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). */
139 struct sigaction sa;
140 memset (&sa, '\0', sizeof (sa));
142 sigset_t hset;
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;
155 else
157 __libc_sigaction (sig, 0, &sa);
158 if (sa.sa_handler == SIG_IGN)
159 continue;
160 sa.sa_handler = SIG_DFL;
163 else
164 continue;
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)
175 goto fail;
177 else if ((attr->__flags & POSIX_SPAWN_SETSCHEDULER) != 0)
179 if ((ret = __sched_setscheduler (0, attr->__policy, &attr->__sp)) == -1)
180 goto fail;
182 #endif
184 /* Set the process group ID. */
185 if ((attr->__flags & POSIX_SPAWN_SETPGROUP) != 0
186 && (ret = __setpgid (0, attr->__pgrp)) != 0)
187 goto fail;
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))
193 goto fail;
195 /* Execute the file actions. */
196 if (file_actions != 0)
198 int cnt;
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)
213 goto fail;
214 p = ret;
217 switch (action->tag)
219 case spawn_do_close:
220 if ((ret =
221 close_not_cancel (action->action.close_action.fd)) != 0)
223 if (!have_fdlimit)
225 __getrlimit64 (RLIMIT_NOFILE, &fdlimit);
226 have_fdlimit = true;
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)
232 goto fail;
234 break;
236 case spawn_do_open:
238 ret = open_not_cancel (action->action.open_action.path,
239 action->action.
240 open_action.oflag | O_LARGEFILE,
241 action->action.open_action.mode);
243 if (ret == -1)
244 goto fail;
246 int new_fd = ret;
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)
253 goto fail;
255 if ((ret = close_not_cancel (new_fd)) != 0)
256 goto fail;
259 break;
261 case spawn_do_dup2:
262 if ((ret = __dup2 (action->action.dup2_action.fd,
263 action->action.dup2_action.newfd))
264 != action->action.dup2_action.newfd)
265 goto fail;
266 break;
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
280 (2.15). */
281 maybe_script_execute (args);
283 ret = -errno;
285 fail:
286 /* Since sizeof errno < PIPE_BUF, the write is atomic. */
287 ret = -ret;
288 if (ret)
289 while (write_not_cancel (p, &ret, sizeof ret) < 0)
290 continue;
291 exit (SPAWN_ERROR);
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. */
296 static int
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 *))
303 pid_t new_pid;
304 struct posix_spawn_args args;
305 int ec;
307 if (__pipe2 (args.pipe, O_CLOEXEC))
308 return errno;
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
312 values. */
313 ptrdiff_t argc = 0;
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
318 argument. */
319 ptrdiff_t limit = INT_MAX - 1;
320 while (argv[argc++] != NULL)
321 if (argc == limit)
323 errno = E2BIG;
324 return errno;
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]);
339 return errno;
342 /* Disable asynchronous cancellation. */
343 int cs = LIBC_CANCEL_ASYNC ();
345 args.file = file;
346 args.exec = exec;
347 args.fa = file_actions;
348 args.attr = attrp ? attrp : &(const posix_spawnattr_t) { 0 };
349 args.argv = argv;
350 args.argc = argc;
351 args.envp = envp;
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
360 a successful execve.
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
364 for instance). */
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]);
370 if (new_pid > 0)
372 if (__read (args.pipe[0], &ec, sizeof ec) != sizeof ec)
373 ec = 0;
374 else
375 __waitpid (new_pid, NULL, 0);
377 else
378 ec = -new_pid;
380 __munmap (stack, stack_size);
382 close_not_cancel (args.pipe[0]);
384 if (!ec && pid)
385 *pid = new_pid;
387 __sigprocmask (SIG_SETMASK, &args.oldmask, 0);
389 LIBC_CANCEL_RESET (cs);
391 return ec;
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);