1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2026 Oxide Computer Company
14 */
15
16 /*
17 * spawn(2): in-kernel process creation for posix_spawn(3C)
18 * --------------------------------------------------------
19 *
20 * posix_spawn(3C) and posix_spawnp(3C) create a new process running a
21 * named program. They were historically implemented in libc on top of
22 * vforkx() where the library borrowed the parent's address space,
23 * stopped every other thread in the process, ran the file actions and
24 * attribute changes in the borrowed image, and exec'd. This was
25 * rather expensive in the face of a highly-threaded parent. Stopping
26 * the other threads serialises a multi-threaded program around each
27 * spawn, and a child that blocks (for example opening a FIFO as a
28 * file action) blocks the whole process with it.
29 *
30 * spawn(2) moves the work into the kernel. It is a private system call,
31 * used only by libc to implement the posix_spawn() family, and is not a
32 * committed interface. The parent describes the whole operation up
33 * front, the kernel creates a child with a single kernel-resident LWP,
34 * and that LWP applies the requested changes to itself and execs the
35 * target. No address space is copied and no threads are stopped. A
36 * process can spawn(2) in all its threads and concurrency is limited
37 * only by locks that need to be held shortly when processes are
38 * created.
39 *
40 * The libc/kernel boundary
41 * ------------------------
42 *
43 * Everything the child needs is marshalled by libc into two flat,
44 * position-independent blobs and copied in as the spawn(2) arguments:
45 *
46 * o spawn_param_t -- the attributes and the ordered file actions.
47 * o spawn_args_t -- the argv and envp string vectors.
48 *
49 * Both have fixed headers that carry byte offsets and counts into a
50 * trailing data[] region. Since the blobs come from userland they are
51 * untrusted; spawn_param_verify() and spawn_args_verify() check every
52 * offset, length and count for consistency and overflow before
53 * anything is dereferenced. Anything malformed results in an EINVAL.
54 *
55 * Creating the child
56 * ------------------
57 *
58 * Process creation reuses cfork(), which recognises a spawn by its
59 * non-NULL kspawn_param_t. Unlike fork() it does not hold the other
60 * LWPs and unlike both fork() and vfork() it neither duplicates nor
61 * borrows the parent's address space. The child is born with a single
62 * LWP, running in the kernel, with kas for its p_as. /proc and
63 * relvm() already treat a process in this state as having no address
64 * space, the same as the window during an ordinary exec. That single
65 * LWP runs spawn_main().
66 *
67 * The child: spawn_main()
68 * -----------------------
69 *
70 * spawn_main() first arranges for the LWP to appear as though it is
71 * returning from an execve(2) call - that is in effect what it is
72 * about to do. It then, in the order the old libc implementation used:
73 *
74 * o applies the attributes - signal mask and dispositions, RESETIDS,
75 * SETSID, SETPGROUP, and last the scheduling class and priority.
76 * These are last so the credential checks see the post-RESETIDS
77 * ids;
78 * o applies the file actions in the caller's order - open, close,
79 * dup2, closefrom, chdir, fchdir;
80 * o execs the target. For posix_spawnp() the PATH search and the
81 * ENOEXEC "run it as a shell script" fallback happen here, in the
82 * child and after the file actions, so a relative PATH entry
83 * resolves against whatever directory the file actions chose.
84 *
85 * On success the LWP enters userland through lwp_rtt_initial() and
86 * the new program runs.
87 *
88 * The handshake
89 * -------------
90 *
91 * The parent's spawn(2) call must not return until the child has
92 * either started its new program or failed, and in the failing case
93 * it must learn the error. The two LWPs synchronise through the
94 * kspawn_param_t (ksp). The parent owns ksp for the whole operation
95 * in that it allocates it, and frees it once the child has signalled.
96 * The child only sets the result and signals, and must not touch it
97 * once it has signalled.
98 *
99 * parent thread -- spawn() child LWP -- spawn_main()
100 * ------------------------ ------------------------
101 * copyin + verify the blob
102 * mutex_enter(ksp_lock)
103 * cfork() -----------------------> p_spawn_ksp = ksp; new LWP runs:
104 * while (!ksp_complete) apply attributes, file actions
105 * cv_wait_sig / cv_wait exec the target
106 * spawn_complete(ksp, err):
107 * ksp_error = err
108 * ksp_complete = true
109 * woken <---------------------------- cv_signal(ksp_cv)
110 * ksp_complete now set, loop ends then one of:
111 * ok -> lwp_rtt_initial()
112 * NOEXECERR -> exit(127)
113 * failed -> CLDEVAPORATE; exit
114 * return pid, or set_errno(ksp_error)
115 *
116 * If we didn't do anything else, a child killed before it reaches
117 * spawn_complete() would leave the parent waiting forever.
118 * proc_exit() deals with this by completing the handshake on the
119 * child's behalf should it exit with p_spawn_ksp still set. Such a
120 * child does not set CLDEVAPORATE, so it becomes an ordinary zombie,
121 * matching a fork(2) child that is killed before it can exec.
122 *
123 * The parent waits with cv_wait_sig() so that job control and /proc
124 * keep their usual effect on it. Once a signal is actually delivered
125 * it switches to an uninterruptible cv_wait(), because it cannot
126 * return and free ksp while the child may still reference it. A fatal
127 * signal aimed only at the parent therefore does not unwedge it until
128 * the child reports back. This is consistent with what happens with a
129 * vfork() parent in vfwait().
130 *
131 * Running without holdlwps
132 * ------------------------
133 *
134 * Skipping holdlwps() is what makes spawn(2) cheap, but it means the
135 * parent's other threads keep running while the child is built. Each
136 * thing the child copies out of the parent must therefore be taken
137 * atomically with respect to those threads:
138 *
139 * o the fd table is copied by flist_spawn(), which locks each
140 * entry as it copies it (see "Copying the file descriptor table"
141 * below);
142 * o the uarea, cwd/root vnodes and signal state are copied in
143 * under p_lock, so a concurrent chdir() or sigaction() cannot
144 * change them.
145 *
146 * That the parent is still running is the main thing to bear in mind
147 * when reading the rest of this file.
148 *
149 * Copying the file descriptor table
150 * ---------------------------------
151 *
152 * The child's descriptor table is built by flist_spawn() rather than
153 * the flist_fork() that fork() and vfork() use. It differs for two
154 * reasons.
155 *
156 * The first is locking, as above. flist_fork() copies the table
157 * without per-entry locks, which is safe only because the other LWPs
158 * are held. flist_spawn() takes each entry's lock as it reads and
159 * copies it, and takes the hold on the underlying file while that
160 * lock is still held, so a sibling thread cannot close the descriptor
161 * and drop its last reference midway through.
162 *
163 * The second is that a spawn is logically equivalent to a fork
164 * immediately followed by an exec, so a descriptor that cannot play
165 * any part in the exec'd image need not be copied at all. Descriptors
166 * are kept only if they would still be present in the new program, or
167 * if a file action needs it first:
168 *
169 * o an FD_CLOFORK descriptor is dropped, as it is by fork();
170 * o a descriptor that is not FD_CLOEXEC and lies below any
171 * closefrom() file action's bound is kept;
172 * o a descriptor named as the source of a dup2 or fchdir file action
173 * is kept even when it is FD_CLOEXEC or above the closefrom bound,
174 * because the action must still read it;
175 * o anything else is dropped.
176 *
177 * A descriptor kept only because an action references it, but which
178 * is FD_CLOEXEC, is still closed by close_exec() at the exec. The set
179 * of descriptors the new program sees is therefore unchanged, the
180 * selective copy being purely an optimisation.
181 *
182 * Skipping descriptors also lets the child's table be sized to the
183 * highest descriptor actually kept, rather than to the parent's
184 * highest. A process that has at some point opened a high-numbered
185 * descriptor (say fd 60000), with FD_CLOEXEC would otherwise force
186 * every child it spawns to allocate a 60000-entry table only to close
187 * it again at exec. Two passes of the table are made. The first finds
188 * the highest kept descriptor and sizes the child's table to it. The
189 * second walks that range and, under each entry's lock, re-evaluates the
190 * keep decision and copies the descriptor. These two passes are not one
191 * atomic snapshot of the whole table. A change a sibling makes within the
192 * sized range is picked up by the second pass, but a descriptor opened
193 * above that range between the passes is not copied by this spawn, the
194 * same way an fd change made concurrently with fork(2) may or may not be
195 * seen by the child. Either way no descriptor is ever torn, since each is
196 * copied while its entry is locked.
197 *
198 * Exec'ing from kernel memory
199 * ---------------------------
200 *
201 * A normal execve(2) reads its argv and envp from the calling
202 * process's user address space. The spawn child has no user address
203 * space yet, and its arguments sit in the marshalled blob in kernel
204 * memory. exec_common() therefore takes a uio_seg_t saying where the
205 * vectors live, and spawn_main() builds native char * arrays that
206 * point into the blob. The standard exec code then copies the strings
207 * onto the new user stack from kernel rather than user memory, but is
208 * otherwise unchanged. Every other caller passes UIO_USERSPACE and
209 * follows the original path.
210 *
211 * Privileges
212 * ----------
213 *
214 * spawn(2) grants nothing that a fork(2) and exec(2) pair could not.
215 * Entry is gated by the same secpolicy_basic_fork() check fork() uses,
216 * and the child runs with the credentials it inherits from the parent.
217 * POSIX_SPAWN_RESETIDS is the only attribute that touches credentials,
218 * and it only ever drops privilege, resetting the effective uid and
219 * gid to the real uid and gid. The exec itself performs the usual
220 * checks on the target, including the handling of set-id binaries,
221 * just as a direct execve(2) would.
222 *
223 * Observability
224 * -------------
225 *
226 * To the proc DTrace provider and to /proc, a spawn looks like a fork
227 * followed by an exec and fires the same probes. While it is being
228 * built the child carries SSPAWNING, which makes /proc control
229 * operations on it fail with EBUSY, as for a system process. A child
230 * whose setup fails evaporates without ever being seen by its parent,
231 * so the new sdt:::spawn-error probe records the failing stage and
232 * errno, and the ::spawn mdb dcmd lists the spawns currently in
233 * flight.
234 *
235 * Before it execs, a spawn child is in the same state as any process
236 * caught partway through an ordinary exec(). In particular it has no
237 * address space of its own (p_as == kas). /proc already knows how to
238 * treat such a process, and the entry points divide into three groups by
239 * how much of that existing handling already covers a spawn child:
240 *
241 * o The observation paths and pr_set() already test p_as == kas and
242 * report a process with no address space as a system process. A
243 * half-built spawn child falls into that same part-exec'd category.
244 *
245 * o The control entry points pr_control[32]() gate only on SSYS,
246 * never on kas. A spawn child is not SSYS, so we also need to
247 * test the SSPAWNING flag here so that an operation such as PCSTOP
248 * does not try to stop a process executing in the kernel.
249 *
250 * o The legacy stop ioctls (PIOCSTOP, PIOCWSTOP) must test both kas
251 * and SSPAWNING, because the kas test has a gap at the tail of
252 * exec. The new address space is installed before SSPAWNING is
253 * cleared and SEXECED set in exec_common(). In that window the
254 * child has its own address space but has not finished exec'ing.
255 *
256 * We deliberately do not expose a dedicated "this is a spawning child"
257 * flag through /proc. This is consistent with what is in place for
258 * a vfork child that has not yet exec'd. If required in the future,
259 * a PR_SPAWNING bit could be added to extend the committed procfs
260 * interface.
261 *
262 * Auditing
263 * --------
264 *
265 * A real fork() followed by an exec() produces two audit records in
266 * two processes - the fork in the parent and the exec in the child. A
267 * spawn is a single system call in the parent, and it audits as one
268 * event, AUE_SPAWN.
269 *
270 * The record is assembled entirely in the parent's spawn(2) context.
271 * The process-creation part is added by audit_newproc() during
272 * getproc(), as it is for fork(). Once the child has reported back,
273 * audit_spawn() adds the exec detail. The path is recorded as a text
274 * token, the attributes of the exec'd file as an attribute token, and,
275 * subject to the audit_argv and audit_arge policies, the argument and
276 * environment vectors are included. The path is ksp_path, which for
277 * posix_spawnp() is the name the child exec'd after the path search,
278 * not necessarily the name the caller passed. In the ENOEXEC shell
279 * fallback case the audited argv is the one the child built - "sh"
280 * followed by the resolved script path and the caller's remaining
281 * arguments - so the record reflects that the shell, not the script,
282 * was the program loaded.
283 */
284
285 #include <sys/class.h>
286 #include <sys/cmn_err.h>
287 #include <sys/cred.h>
288 #include <sys/ddi.h>
289 #include <sys/debug.h>
290 #include <sys/errno.h>
291 #include <sys/exec.h>
292 #include <sys/fcntl.h>
293 #include <sys/file.h>
294 #include <sys/fork.h>
295 #include <sys/kmem.h>
296 #include <sys/param.h>
297 #include <sys/pgrpsys.h>
298 #include <sys/proc.h>
299 #include <sys/sdt.h>
300 #include <sys/signal.h>
301 #include <sys/spawn.h>
302 #include <sys/spawn_impl.h>
303 #include <sys/sunddi.h>
304 #include <sys/syscall.h>
305 #include <sys/sysmacros.h>
306 #include <sys/systm.h>
307 #include <sys/types.h>
308 #include <sys/vnode.h>
309
310 #include <c2/audit.h>
311
312 extern int64_t cfork(int, int, kspawn_param_t *, int);
313
314 extern int setpgrp(int, int, int);
315 extern int setuid(uid_t);
316 extern int setgid(gid_t);
317 extern int fchdir(int);
318 extern int kchdir(const char *);
319 extern int64_t lwp_sigmask(int, uint_t, uint_t, uint_t, uint_t);
320 extern int setthreadprio(pcprio_t *, kthread_t *);
321
322 static const spawn_attr_t *
spawn_param_attr(const spawn_param_t * sp)323 spawn_param_attr(const spawn_param_t *sp)
324 {
325 if (sp == NULL || sp->sp_attr_len == 0)
326 return (NULL);
327 return ((const spawn_attr_t *)&sp->sp_data[sp->sp_attr_off]);
328 }
329
330 /*
331 * Signal completion to the parent which is waiting in spawn(2).
332 */
333 void
spawn_complete(kspawn_param_t * ksp,int err)334 spawn_complete(kspawn_param_t *ksp, int err)
335 {
336 curproc->p_spawn_ksp = NULL;
337
338 mutex_enter(&ksp->ksp_lock);
339 ksp->ksp_error = err;
340 ksp->ksp_complete = true;
341 cv_signal(&ksp->ksp_cv);
342 mutex_exit(&ksp->ksp_lock);
343 }
344
345 /*
346 * Apply the spawn attributes in the child.
347 */
348 static int
spawn_attrs_apply(const spawn_param_t * sp)349 spawn_attrs_apply(const spawn_param_t *sp)
350 {
351 const spawn_attr_t *spa = spawn_param_attr(sp);
352 klwp_t *lwp = ttolwp(curthread);
353 proc_t *p = curproc;
354 int sig;
355
356 if (spa == NULL)
357 return (0);
358
359 if (spa->sa_psflags & POSIX_SPAWN_SETSIGMASK) {
360 (void) lwp_sigmask(SIG_SETMASK,
361 spa->sa_sigmask.__sigbits[0],
362 spa->sa_sigmask.__sigbits[1],
363 spa->sa_sigmask.__sigbits[2],
364 spa->sa_sigmask.__sigbits[3]);
365 }
366
367 if (spa->sa_psflags & POSIX_SPAWN_SETSIGIGN_NP) {
368 k_sigset_t kset;
369
370 sigutok(&spa->sa_sigignore, &kset);
371 for (sig = 1; sig < NSIG; sig++) {
372 if (sigismember(&kset, sig) &&
373 !sigismember(&cantmask, sig)) {
374 mutex_enter(&p->p_lock);
375 setsigact(sig, SIG_IGN, &nullsmask, 0);
376 mutex_exit(&p->p_lock);
377 }
378 }
379 }
380
381 if (spa->sa_psflags & POSIX_SPAWN_SETSIGDEF) {
382 k_sigset_t kset;
383
384 sigutok(&spa->sa_sigdefault, &kset);
385 for (sig = 1; sig < NSIG; sig++) {
386 if (sigismember(&kset, sig) &&
387 !sigismember(&cantmask, sig)) {
388 mutex_enter(&p->p_lock);
389 setsigact(sig, SIG_DFL, &nullsmask, 0);
390 mutex_exit(&p->p_lock);
391 }
392 }
393 }
394
395 if (spa->sa_psflags & POSIX_SPAWN_RESETIDS) {
396 lwp->lwp_errno = 0;
397 if (setgid(crgetrgid(CRED())) != 0 ||
398 setuid(crgetruid(CRED())) != 0) {
399 return (lwp->lwp_errno);
400 }
401 }
402
403 if (spa->sa_psflags & POSIX_SPAWN_SETSID) {
404 /*
405 * setpgrp() reports failure through lwp_errno. Its return
406 * value with the SETSID subcommand is a session ID.
407 */
408 lwp->lwp_errno = 0;
409 (void) setpgrp(PGRPSYS_SETSID, 0, 0);
410 if (lwp->lwp_errno != 0)
411 return (lwp->lwp_errno);
412 }
413
414 if (spa->sa_psflags & POSIX_SPAWN_SETPGROUP) {
415 lwp->lwp_errno = 0;
416 if (setpgrp(PGRPSYS_SETPGID, 0, spa->sa_pgroup) != 0)
417 return (lwp->lwp_errno);
418 }
419
420 /*
421 * The scheduling attributes are applied last, once any RESETIDS,
422 * SETSID and SETPGROUP changes are in place. RESETIDS in particular
423 * must come first so that the privilege checks made while setting the
424 * scheduling parameters see the child's final credentials.
425 */
426 if ((spa->sa_psflags &
427 (POSIX_SPAWN_SETSCHEDULER | POSIX_SPAWN_SETSCHEDPARAM)) != 0) {
428 kspawn_sched_t ks;
429 int err = 0;
430
431 bcopy(&sp->sp_data[sp->sp_sched_off], &ks, sizeof (ks));
432
433 switch (ks.ksched_op) {
434 case KSCHED_PARMS:
435 err = parmsin(&ks.ksched_parms, NULL);
436 break;
437 case KSCHED_PRIO:
438 /* The same check that doprio() applies */
439 if (ks.ksched_prio.pc_cid >= loaded_classes ||
440 ks.ksched_prio.pc_cid < 1) {
441 err = EINVAL;
442 }
443 break;
444 }
445
446 if (err != 0)
447 return (err);
448
449 mutex_enter(&pidlock);
450 mutex_enter(&p->p_lock);
451 if (ks.ksched_op == KSCHED_PARMS)
452 err = parmsset(&ks.ksched_parms, curthread);
453 else
454 err = setthreadprio(&ks.ksched_prio, curthread);
455 mutex_exit(&p->p_lock);
456 mutex_exit(&pidlock);
457
458 if (err != 0)
459 return (err);
460 }
461
462 return (0);
463 }
464
465 static int
spawn_factions_apply(const kspawn_param_t * ksp)466 spawn_factions_apply(const kspawn_param_t *ksp)
467 {
468 const spawn_param_t *sp = ksp->ksp_param;
469 klwp_t *lwp = ttolwp(curthread);
470 uint32_t off;
471
472 if (sp == NULL || sp->sp_fattr_cnt == 0)
473 return (0);
474
475 off = sp->sp_fattr_off;
476 for (uint32_t i = 0; i < sp->sp_fattr_cnt; i++) {
477 const kfile_attr_t *kfa =
478 (const kfile_attr_t *)&sp->sp_data[off];
479 int err = 0;
480 int fd;
481
482 switch (kfa->kfa_type) {
483 case FA_OPEN:
484 fd = kopenat(AT_FDCWD, (char *)kfa->kfa_path,
485 kfa->kfa_oflag, kfa->kfa_mode,
486 ksp->ksp_parent_model);
487 if (fd < 0) {
488 err = lwp->lwp_errno;
489 } else if (fd != kfa->kfa_filedes) {
490 err = fdup2(fd, kfa->kfa_filedes);
491 (void) closeandsetf(fd, NULL);
492 }
493 break;
494 case FA_CLOSE:
495 err = closeandsetf(kfa->kfa_filedes, NULL);
496 /* An already-closed descriptor is not an error */
497 if (err == EBADF)
498 err = 0;
499 break;
500 case FA_DUP2:
501 err = fdup2(kfa->kfa_filedes, kfa->kfa_newfiledes);
502 break;
503 case FA_CLOSEFROM:
504 closefrom_all(kfa->kfa_filedes);
505 break;
506 case FA_CHDIR:
507 err = kchdir((const char *)kfa->kfa_path);
508 break;
509 case FA_FCHDIR:
510 lwp->lwp_errno = 0;
511 if (fchdir(kfa->kfa_filedes) != 0)
512 err = lwp->lwp_errno;
513 break;
514 }
515
516 if (err != 0)
517 return (err);
518
519 off += kfa->kfa_len;
520 }
521
522 return (0);
523 }
524
525 /*
526 * Build a NULL-terminated vector of pointers to the packed, NUL-terminated
527 * strings in the spawn args data area.
528 */
529 static char **
spawn_vector(const spawn_args_t * sa,uint32_t off,uint32_t cnt)530 spawn_vector(const spawn_args_t *sa, uint32_t off, uint32_t cnt)
531 {
532 char **vec = kmem_alloc(((size_t)cnt + 1) * sizeof (char *), KM_SLEEP);
533
534 for (uint32_t i = 0; i < cnt; i++) {
535 vec[i] = (char *)&sa->sa_data[off];
536 off += strlen(vec[i]) + 1;
537 }
538 vec[cnt] = NULL;
539
540 return (vec);
541 }
542
543 /*
544 * Build the path name for the next attempt in a PATH search by joining the
545 * leading component of the search path with the program name. Returns the
546 * remainder of the search path or NULL if we're done. Sets *fits to false
547 * if the joined name would not fit in buf, in which case buf is not filled
548 * and the caller must skip this candidate rather than exec a truncated path.
549 */
550 static const char *
spawn_execat(const char * path,const char * name,char * buf,size_t bufl,bool * fits)551 spawn_execat(const char *path, const char *name, char *buf, size_t bufl,
552 bool *fits)
553 {
554 const char *sep = strchr(path, ':');
555 size_t dirlen = (sep == NULL) ? strlen(path) : (size_t)(sep - path);
556 size_t namelen = strlen(name);
557 size_t need = dirlen + namelen + 1;
558 char *s = buf;
559
560 if (dirlen > 0)
561 need++; /* for the '/' separator */
562
563 *fits = (need <= bufl);
564 if (*fits) {
565 bcopy(path, s, dirlen);
566 s += dirlen;
567 if (dirlen > 0)
568 *s++ = '/';
569 bcopy(name, s, namelen);
570 s[namelen] = '\0';
571 }
572
573 return (sep != NULL ? sep + 1 : NULL);
574 }
575
576 /*
577 * Record the attributes of the file we have just exec'd so that the parent can
578 * include them in the spawn(2) audit record, the same attribute token an
579 * ordinary exec(2) produces. The exec'd file is now the process's p_exec. This
580 * runs in the child after a successful exec_common() and before it reports back
581 * to the parent, so the parent sees the result. It is only worth the
582 * vop_getattr() when auditing is active.
583 */
584 static void
spawn_capture_vattr(kspawn_param_t * ksp)585 spawn_capture_vattr(kspawn_param_t *ksp)
586 {
587 if (!ksp->ksp_audit)
588 return;
589
590 ksp->ksp_vattr.va_mask = AT_ALL;
591 if (VOP_GETATTR(curproc->p_exec, &ksp->ksp_vattr, 0, CRED(), NULL) == 0)
592 ksp->ksp_have_vattr = true;
593 }
594
595 /*
596 * Marshal the argument vector the child actually exec'd into ksp_argv, as a run
597 * of nul-terminated strings, so the parent audits it in place of the caller's
598 * argv. This is only needed for the ENOEXEC shell fallback and only when
599 * auditing is active.
600 */
601 static void
spawn_capture_argv(kspawn_param_t * ksp,char * const * argv)602 spawn_capture_argv(kspawn_param_t *ksp, char *const *argv)
603 {
604 size_t sz = 0;
605 uint_t argc = 0;
606 char *p;
607
608 if (!ksp->ksp_audit)
609 return;
610
611 for (uint_t i = 0; argv[i] != NULL; i++) {
612 sz += strlen(argv[i]) + 1;
613 argc++;
614 }
615 if (sz == 0)
616 return;
617
618 p = kmem_alloc(sz, KM_SLEEP);
619 ksp->ksp_argv = p;
620 ksp->ksp_argvsz = sz;
621 ksp->ksp_argc = argc;
622 for (uint_t i = 0; argv[i] != NULL; i++) {
623 size_t len = strlen(argv[i]) + 1;
624
625 bcopy(argv[i], p, len);
626 p += len;
627 }
628 }
629
630 /*
631 * Exec the target program. For posix_spawn() this is a single attempt at the
632 * given path. For posix_spawnp(), libc supplies the search path and shell in
633 * the spawn parameters, and we need to walk the path.
634 *
635 * On success the process is running the new image and this returns 0.
636 */
637 static int
spawn_exec(kspawn_param_t * ksp)638 spawn_exec(kspawn_param_t *ksp)
639 {
640 const spawn_args_t *sa = ksp->ksp_args;
641 const spawn_param_t *sp = ksp->ksp_param;
642 const char *pathstr = NULL, *shell = NULL, *cp;
643 /*
644 * Allow for prepending "./" below, should the resulting filename begin
645 * with a '-'.
646 */
647 const size_t pathl = MAXPATHLEN + sizeof ("./");
648 char **argv, **envp;
649 char *path = NULL;
650 int err = ENOENT;
651 int saved_err = 0;
652
653 argv = spawn_vector(sa, sa->sa_arg_off, sa->sa_arg_cnt);
654 envp = spawn_vector(sa, sa->sa_env_off, sa->sa_env_cnt);
655
656 if (sp != NULL && sp->sp_path_len != 0) {
657 pathstr = (const char *)&sp->sp_data[sp->sp_path_off];
658 if (sp->sp_shell_len != 0)
659 shell = (const char *)&sp->sp_data[sp->sp_shell_off];
660 }
661
662 if (pathstr == NULL) {
663 /* posix_spawn() - the simple case with the given path */
664 err = exec_common(ksp->ksp_path, (const char **)argv,
665 (const char **)envp, NULL, EBA_NONE, UIO_SYSSPACE);
666 if (err == 0)
667 spawn_capture_vattr(ksp);
668 goto out;
669 }
670
671 path = kmem_alloc(pathl, KM_SLEEP);
672
673 cp = pathstr;
674 do {
675 bool fits;
676
677 cp = spawn_execat(cp, ksp->ksp_path, path, MAXPATHLEN + 1,
678 &fits);
679 if (!fits) {
680 /*
681 * This candidate does not fit in the buffer. Skip it
682 * rather than exec a truncated path, remembering the
683 * error in case the search finds nothing better.
684 */
685 err = ENAMETOOLONG;
686 if (saved_err == 0)
687 saved_err = ENAMETOOLONG;
688 continue;
689 }
690
691 /*
692 * If the resulting filename begins with a '-', prepend "./"
693 * so that the shell cannot interpret it as an option.
694 */
695 if (*path == '-') {
696 memmove(path + 2, path, strlen(path) + 1);
697 path[0] = '.';
698 path[1] = '/';
699 }
700
701 err = exec_common(path, (const char **)argv,
702 (const char **)envp, NULL, EBA_NONE, UIO_SYSSPACE);
703 if (err == 0) {
704 /*
705 * Record the path the search resolved to so
706 * the parent can audit it. The copy will fit
707 * in ksp_path since our call to exec_common()
708 * succeeded with this path.
709 */
710 (void) strlcpy(ksp->ksp_path, path,
711 sizeof (ksp->ksp_path));
712 spawn_capture_vattr(ksp);
713 goto out;
714 }
715
716 /*
717 * Remember the most meaningful error seen during the search
718 * (matching execvp). A candidate that existed but could not be
719 * executed (EACCES) outranks both a later "not found" and an
720 * over-long candidate that we had to skip.
721 */
722 if (err == EACCES)
723 saved_err = EACCES;
724
725 /*
726 * The candidate has execute permission but is not in a
727 * format the kernel recognises. That is, it is neither a
728 * binary nor a "#!" script, both of which the kernel's exec
729 * would run directly. We treat it as a bare shell script
730 * and re-exec it through the shell interpreter passed in
731 * from userland ("sh"), reproducing the historical
732 * execvp()-based posix_spawnp(). The PATH search stops
733 * here.
734 *
735 * Note that POSIX.1-2024 (Issue 8) now requires
736 * posix_spawnp() to fail with ENOEXEC here rather than fall
737 * back to sh (see Austin Group defect 1674). However, we
738 * keep the fallback for now to preserve the execvp()
739 * behaviour that callers may rely on.
740 */
741 if (err == ENOEXEC) {
742 size_t nargs = (size_t)sa->sa_arg_cnt + 3;
743 char **newargs;
744 uint32_t i;
745
746 if (shell == NULL)
747 goto out;
748
749 newargs = kmem_alloc(nargs * sizeof (char *),
750 KM_SLEEP);
751 /*
752 * argv[0] is always the literal "sh", regardless of
753 * the shell path supplied by libc, matching the
754 * behaviour of execvp().
755 */
756 newargs[0] = "sh";
757 newargs[1] = path;
758 for (i = 1; i < sa->sa_arg_cnt; i++)
759 newargs[i + 1] = argv[i];
760 newargs[i + 1] = NULL;
761
762 err = exec_common(shell, (const char **)newargs,
763 (const char **)envp, NULL, EBA_NONE,
764 UIO_SYSSPACE);
765 if (err == 0) {
766 (void) strlcpy(ksp->ksp_path, shell,
767 sizeof (ksp->ksp_path));
768 spawn_capture_vattr(ksp);
769 spawn_capture_argv(ksp, newargs);
770 }
771
772 kmem_free(newargs, nargs * sizeof (char *));
773 goto out;
774 }
775 } while (cp != NULL);
776
777 /*
778 * The search is exhausted without an exec. Prefer the most
779 * meaningful error we saw over whichever happened to be last.
780 */
781 if (saved_err != 0)
782 err = saved_err;
783
784 out:
785 if (path != NULL)
786 kmem_free(path, pathl);
787 kmem_free(argv, ((size_t)sa->sa_arg_cnt + 1) * sizeof (char *));
788 kmem_free(envp, ((size_t)sa->sa_env_cnt + 1) * sizeof (char *));
789
790 return (err);
791 }
792
793 /*
794 * The entry point for the single LWP of a spawned child, which begins life
795 * here in the kernel. Apply the spawn attributes and file actions, exec the
796 * target program, report the outcome to the waiting parent and, if
797 * everything's ok, enter userland via lwp_rtt_initial().
798 */
799 void
spawn_main(void * arg)800 spawn_main(void *arg)
801 {
802 kspawn_param_t *ksp = arg;
803 klwp_t *lwp = ttolwp(curthread);
804 proc_t *p = curproc;
805 const spawn_attr_t *spa = spawn_param_attr(ksp->ksp_param);
806 bool execfail = false;
807 int err;
808
809 ASSERT(p->p_spawn_ksp == ksp);
810
811 /*
812 * Make this LWP look as if it is completing an execve() system
813 * call. /proc and post_syscall() rely on this.
814 */
815 bzero(lwp->lwp_arg, sizeof (lwp->lwp_arg));
816 lwp->lwp_ap = lwp->lwp_arg;
817 curthread->t_sysnum = SYS_execve;
818 curthread->t_post_sys = 1;
819
820 /*
821 * The spawn-error probes identify the spawn parameters, the stage
822 * at which the spawn failed and the error. A failed spawn child
823 * usually evaporates without ever running in userland, and its
824 * image is still the parent's, so these probes are the observable
825 * record of what went wrong inside it.
826 */
827 if ((err = spawn_attrs_apply(ksp->ksp_param)) != 0) {
828 DTRACE_PROBE3(spawn__error, kspawn_param_t *, ksp,
829 char *, "attributes", int, err);
830 } else if ((err = spawn_factions_apply(ksp)) != 0) {
831 DTRACE_PROBE3(spawn__error, kspawn_param_t *, ksp,
832 char *, "file-actions", int, err);
833 } else if ((err = spawn_exec(ksp)) != 0) {
834 DTRACE_PROBE3(spawn__error, kspawn_param_t *, ksp,
835 char *, "exec", int, err);
836 execfail = true;
837 }
838
839 if (err == 0) {
840 /*
841 * The exec succeeded. Release the parent and enter userland
842 * in the new program.
843 */
844 spawn_complete(ksp, 0);
845 lwp_rtt_initial();
846 /* NOTREACHED */
847 }
848
849 if (execfail && spa != NULL &&
850 (spa->sa_psflags & POSIX_SPAWN_NOEXECERR_NP) != 0) {
851 /*
852 * POSIX_SPAWN_NOEXECERR_NP: an exec failure is not reported
853 * to the parent. It is told that the spawn succeeded, and
854 * the child exits with status 127 for the parent to observe
855 * via wait().
856 */
857 spawn_complete(ksp, 0);
858 exit(CLD_EXITED, SPAWN_NOEXECERR_STATUS);
859 /* NOTREACHED */
860 }
861
862 /*
863 * The error is reported to the parent and the parent never learns
864 * this child's pid - it disappears without a trace and without
865 * raising SIGCHLD.
866 */
867 mutex_enter(&pidlock);
868 p->p_pidflag |= CLDEVAPORATE;
869 mutex_exit(&pidlock);
870
871 spawn_complete(ksp, err);
872 exit(CLD_EXITED, 0);
873 /* NOTREACHED */
874 }
875
876 static bool
spawn_region_ok(const spawn_param_t * sp,uint32_t off,uint32_t len)877 spawn_region_ok(const spawn_param_t *sp, uint32_t off, uint32_t len)
878 {
879 return (off <= sp->sp_datalen && len <= sp->sp_datalen - off);
880 }
881
882 /*
883 * As spawn_region_ok(), additionally requiring that the region holds a
884 * NUL-terminated string.
885 */
886 static bool
spawn_str_ok(const spawn_param_t * sp,uint32_t off,uint32_t len)887 spawn_str_ok(const spawn_param_t *sp, uint32_t off, uint32_t len)
888 {
889 return (len != 0 && spawn_region_ok(sp, off, len) &&
890 sp->sp_data[off + len - 1] == '\0');
891 }
892
893 static int
spawn_param_verify(const spawn_param_t * sp,uint32_t spsize)894 spawn_param_verify(const spawn_param_t *sp, uint32_t spsize)
895 {
896 int schedflags = 0;
897
898 if (sp->sp_size != spsize ||
899 sp->sp_datalen != spsize - offsetof(spawn_param_t, sp_data)) {
900 return (EINVAL);
901 }
902
903 if (sp->sp_attr_len != 0) {
904 const spawn_attr_t *spa;
905
906 if (sp->sp_attr_len != sizeof (spawn_attr_t) ||
907 !IS_P2ALIGNED(sp->sp_attr_off, sizeof (uint32_t)) ||
908 !spawn_region_ok(sp, sp->sp_attr_off, sp->sp_attr_len)) {
909 return (EINVAL);
910 }
911
912 spa = spawn_param_attr(sp);
913
914 if ((spa->sa_psflags & ~ALL_POSIX_SPAWN_FLAGS) != 0)
915 return (EINVAL);
916 if (spa->sa_pgroup < 0)
917 return (EINVAL);
918
919 schedflags = spa->sa_psflags &
920 (POSIX_SPAWN_SETSCHEDULER | POSIX_SPAWN_SETSCHEDPARAM);
921 } else if (sp->sp_attr_off != 0) {
922 return (EINVAL);
923 }
924
925 /*
926 * The resolved scheduling attributes are required when one of the
927 * scheduling flags is set, and must not be present otherwise.
928 */
929 if (schedflags != 0) {
930 const kspawn_sched_t *ks;
931
932 if (sp->sp_sched_len != sizeof (kspawn_sched_t) ||
933 !IS_P2ALIGNED(sp->sp_sched_off, sizeof (uint32_t)) ||
934 !spawn_region_ok(sp, sp->sp_sched_off, sp->sp_sched_len)) {
935 return (EINVAL);
936 }
937
938 ks = (const kspawn_sched_t *)&sp->sp_data[sp->sp_sched_off];
939
940 switch (ks->ksched_op) {
941 case KSCHED_PARMS:
942 break;
943 case KSCHED_PRIO:
944 if (ks->ksched_prio.pc_op != PC_SETPRIO)
945 return (EINVAL);
946 break;
947 default:
948 return (EINVAL);
949 }
950 } else if (sp->sp_sched_len != 0 || sp->sp_sched_off != 0) {
951 return (EINVAL);
952 }
953
954 if (sp->sp_fattr_cnt != 0) {
955 uint32_t off = sp->sp_fattr_off;
956
957 if (!IS_P2ALIGNED(off, sizeof (uint32_t)))
958 return (EINVAL);
959
960 for (uint32_t i = 0; i < sp->sp_fattr_cnt; i++) {
961 const kfile_attr_t *kfa;
962 uint64_t reclen;
963
964 if (!spawn_region_ok(sp, off, sizeof (kfile_attr_t)))
965 return (EINVAL);
966
967 kfa = (const kfile_attr_t *)&sp->sp_data[off];
968
969 /*
970 * Each record is padded so that the next one remains
971 * 32-bit aligned.
972 */
973 reclen = P2ROUNDUP((uint64_t)sizeof (kfile_attr_t) +
974 kfa->kfa_pathsize, sizeof (uint32_t));
975 if (kfa->kfa_len != reclen ||
976 !spawn_region_ok(sp, off, kfa->kfa_len)) {
977 return (EINVAL);
978 }
979
980 /*
981 * Each action uses only some of these fields. The
982 * rest may hold arbitrary values, so an action's
983 * consumer must read only the fields for its type.
984 */
985 switch (kfa->kfa_type) {
986 case FA_OPEN:
987 /*
988 * kfa_oflag and kfa_mode are not checked
989 * here. kopenat() interprets them when the
990 * action runs, as open(2) would.
991 */
992 if (kfa->kfa_filedes < 0)
993 return (EINVAL);
994 /* FALLTHROUGH */
995 case FA_CHDIR:
996 if (kfa->kfa_pathsize == 0 ||
997 kfa->kfa_path[kfa->kfa_pathsize - 1] !=
998 '\0') {
999 return (EINVAL);
1000 }
1001 break;
1002 case FA_CLOSE:
1003 case FA_CLOSEFROM:
1004 case FA_FCHDIR:
1005 if (kfa->kfa_pathsize != 0 ||
1006 kfa->kfa_filedes < 0) {
1007 return (EINVAL);
1008 }
1009 break;
1010 case FA_DUP2:
1011 if (kfa->kfa_pathsize != 0 ||
1012 kfa->kfa_filedes < 0 ||
1013 kfa->kfa_newfiledes < 0) {
1014 return (EINVAL);
1015 }
1016 break;
1017 default:
1018 return (EINVAL);
1019 }
1020
1021 off += kfa->kfa_len;
1022 }
1023 } else if (sp->sp_fattr_off != 0) {
1024 return (EINVAL);
1025 }
1026
1027 if (sp->sp_shell_len != 0) {
1028 if (!spawn_str_ok(sp, sp->sp_shell_off, sp->sp_shell_len))
1029 return (EINVAL);
1030 } else if (sp->sp_shell_off != 0) {
1031 return (EINVAL);
1032 }
1033
1034 if (sp->sp_path_len != 0) {
1035 if (!spawn_str_ok(sp, sp->sp_path_off, sp->sp_path_len))
1036 return (EINVAL);
1037 } else if (sp->sp_path_off != 0) {
1038 return (EINVAL);
1039 }
1040
1041 return (0);
1042 }
1043
1044 static int
spawn_args_verify(const spawn_args_t * sa,uint32_t sasize)1045 spawn_args_verify(const spawn_args_t *sa, uint32_t sasize)
1046 {
1047 uint32_t off;
1048
1049 if (sa->sa_size != sasize ||
1050 sa->sa_datalen != sasize - offsetof(spawn_args_t, sa_data)) {
1051 return (EINVAL);
1052 }
1053
1054 if (sa->sa_env_off > sa->sa_datalen ||
1055 sa->sa_arg_off > sa->sa_env_off) {
1056 return (EINVAL);
1057 }
1058
1059 off = sa->sa_arg_off;
1060 for (uint32_t i = 0; i < sa->sa_arg_cnt; i++) {
1061 const char *s = (const char *)&sa->sa_data[off];
1062 const char *e = memchr(s, '\0', sa->sa_env_off - off);
1063
1064 if (e == NULL)
1065 return (EINVAL);
1066 off += (uint32_t)(e - s) + 1;
1067 }
1068 if (off != sa->sa_env_off)
1069 return (EINVAL);
1070
1071 for (uint32_t i = 0; i < sa->sa_env_cnt; i++) {
1072 const char *s = (const char *)&sa->sa_data[off];
1073 const char *e = memchr(s, '\0', sa->sa_datalen - off);
1074
1075 if (e == NULL)
1076 return (EINVAL);
1077 off += (uint32_t)(e - s) + 1;
1078 }
1079 if (off != sa->sa_datalen)
1080 return (EINVAL);
1081
1082 return (0);
1083 }
1084
1085 /*
1086 * Pre-scan the file actions to determine which of the parent's file
1087 * descriptors the child actually needs, so that flist_spawn() can limit its
1088 * copy of the descriptor table:
1089 *
1090 * - ksp_closefrom is the lowest closefrom() bound. Descriptors at or above
1091 * it would be closed by the closefrom action anyway, so they need not be
1092 * copied unless an action consumes them as a source.
1093 * - ksp_reffds lists the descriptors that actions consume as sources -
1094 * dup2() and fchdir() - which must be copied even if they carry
1095 * FD_CLOEXEC or sit above the closefrom bound.
1096 *
1097 * This is purely an optimisation. Copying too much is harmless since
1098 * the file actions and close_exec() still run in the child.
1099 */
1100 static void
spawn_prescan(const spawn_param_t * sp,kspawn_param_t * ksp)1101 spawn_prescan(const spawn_param_t *sp, kspawn_param_t *ksp)
1102 {
1103 const kfile_attr_t *kfa;
1104 uint32_t off, i, n;
1105
1106 ksp->ksp_closefrom = INT_MAX;
1107
1108 if (sp == NULL || sp->sp_fattr_cnt == 0)
1109 return;
1110
1111 n = 0;
1112 off = sp->sp_fattr_off;
1113 for (i = 0; i < sp->sp_fattr_cnt; i++) {
1114 kfa = (const kfile_attr_t *)&sp->sp_data[off];
1115 switch (kfa->kfa_type) {
1116 case FA_CLOSEFROM:
1117 ksp->ksp_closefrom =
1118 MIN(ksp->ksp_closefrom, kfa->kfa_filedes);
1119 break;
1120 case FA_DUP2:
1121 case FA_FCHDIR:
1122 n++;
1123 break;
1124 default:
1125 break;
1126 }
1127 off += kfa->kfa_len;
1128 }
1129
1130 if (n == 0)
1131 return;
1132
1133 /* We saw at least one dup2 or chdir. Build a list of source fds */
1134
1135 ksp->ksp_reffds = kmem_alloc(n * sizeof (int), KM_SLEEP);
1136 ksp->ksp_nreffds = n;
1137
1138 n = 0;
1139 off = sp->sp_fattr_off;
1140 for (i = 0; i < sp->sp_fattr_cnt; i++) {
1141 kfa = (const kfile_attr_t *)&sp->sp_data[off];
1142 if (kfa->kfa_type == FA_DUP2 || kfa->kfa_type == FA_FCHDIR) {
1143 VERIFY3U(n, <, ksp->ksp_nreffds);
1144 ksp->ksp_reffds[n++] = kfa->kfa_filedes;
1145 }
1146 off += kfa->kfa_len;
1147 }
1148 }
1149
1150 static int
spawn_forkflags(const spawn_param_t * sp)1151 spawn_forkflags(const spawn_param_t *sp)
1152 {
1153 const spawn_attr_t *spa = spawn_param_attr(sp);
1154 int flags = 0;
1155
1156 if (spa != NULL) {
1157 if ((spa->sa_psflags & POSIX_SPAWN_NOSIGCHLD_NP) != 0)
1158 flags |= FORK_NOSIGCHLD;
1159 if ((spa->sa_psflags & POSIX_SPAWN_WAITPID_NP) != 0)
1160 flags |= FORK_WAITPID;
1161 }
1162
1163 return (flags);
1164 }
1165
1166 int64_t
spawn(void * path,void * sparam,uint32_t spsize,void * sargs,uint32_t sasize)1167 spawn(void *path, void *sparam, uint32_t spsize, void *sargs, uint32_t sasize)
1168 {
1169 kspawn_param_t *ksp = NULL;
1170 spawn_param_t *sp = NULL;
1171 spawn_args_t *sa = NULL;
1172 int64_t ret = -1;
1173 int err = 0;
1174
1175 if (path == NULL || sargs == NULL || sasize < sizeof (*sa))
1176 return ((int64_t)set_errno(EINVAL));
1177
1178 if (spsize > NCARGS64 || sasize > NCARGS64)
1179 return ((int64_t)set_errno(E2BIG));
1180
1181 if (spsize > 0) {
1182 if (spsize < sizeof (*sp))
1183 return ((int64_t)set_errno(EINVAL));
1184
1185 sp = kmem_alloc(spsize, KM_SLEEP);
1186 if (copyin(sparam, sp, spsize) != 0) {
1187 err = EFAULT;
1188 goto out;
1189 }
1190 if ((err = spawn_param_verify(sp, spsize)) != 0)
1191 goto out;
1192 }
1193
1194 sa = kmem_alloc(sasize, KM_SLEEP);
1195 if (copyin(sargs, sa, sasize) != 0) {
1196 err = EFAULT;
1197 goto out;
1198 }
1199 if ((err = spawn_args_verify(sa, sasize)) != 0)
1200 goto out;
1201
1202 ksp = kmem_zalloc(sizeof (*ksp), KM_SLEEP);
1203
1204 err = copyinstr(path, ksp->ksp_path, sizeof (ksp->ksp_path), NULL);
1205 if (err != 0)
1206 goto out;
1207
1208 ksp->ksp_param = sp;
1209 ksp->ksp_args = sa;
1210 ksp->ksp_parent_model = get_udatamodel();
1211 ksp->ksp_audit = AU_AUDITING();
1212 spawn_prescan(sp, ksp);
1213
1214 mutex_init(&ksp->ksp_lock, NULL, MUTEX_DEFAULT, NULL);
1215 cv_init(&ksp->ksp_cv, NULL, CV_DEFAULT, NULL);
1216
1217 /*
1218 * If cfork() succeeds, wait for the child to apply the various spawn
1219 * attributes and attempt the exec. Every child exit path signals
1220 * completion, including abnormal termination, so the wait is bounded
1221 * by the child's lifetime.
1222 *
1223 * This logic is taken from vfwait(). We wait interruptibly with
1224 * cv_wait_sig() for its jobcontrol and /proc side effects. The
1225 * spawning thread can then be stopped or examined and does not block a
1226 * concurrent holdlwps() from another of the parent's threads while it
1227 * waits. Once a signal is pending we must switch to an uninterruptible
1228 * cv_wait(), since we cannot return and free ksp while the child may
1229 * still reference it, and cv_wait_sig() would otherwise spin returning
1230 * immediately.
1231 */
1232 mutex_enter(&ksp->ksp_lock);
1233 ret = cfork(0, 0, ksp, spawn_forkflags(sp));
1234 if (ttolwp(curthread)->lwp_errno == 0) {
1235 bool signalled = false;
1236
1237 while (!ksp->ksp_complete) {
1238 if (signalled) {
1239 cv_wait(&ksp->ksp_cv, &ksp->ksp_lock);
1240 } else {
1241 signalled = !cv_wait_sig(&ksp->ksp_cv,
1242 &ksp->ksp_lock);
1243 }
1244 }
1245 if (ksp->ksp_error != 0) {
1246 err = ksp->ksp_error;
1247 ret = -1;
1248 }
1249 }
1250 mutex_exit(&ksp->ksp_lock);
1251
1252 mutex_destroy(&ksp->ksp_lock);
1253 cv_destroy(&ksp->ksp_cv);
1254
1255 /*
1256 * Record the details of the spawn while the marshalled data is still
1257 * to hand. On success ksp_path holds the path that the child actually
1258 * exec'd, which for posix_spawnp() may differ from the caller-supplied
1259 * name. The target's attributes are in ksp_vattr and ksp_argv holds
1260 * the vector it exec'd when that differs from the caller's argv.
1261 */
1262 if (ksp->ksp_audit) {
1263 const char *argstr;
1264 ssize_t argc;
1265
1266 if (ksp->ksp_argv != NULL) {
1267 argstr = ksp->ksp_argv;
1268 argc = (ssize_t)ksp->ksp_argc;
1269 } else {
1270 argstr = (const char *)&sa->sa_data[sa->sa_arg_off];
1271 argc = (ssize_t)sa->sa_arg_cnt;
1272 }
1273
1274 audit_spawn(ksp->ksp_path,
1275 ksp->ksp_have_vattr ? &ksp->ksp_vattr : NULL,
1276 argstr, (const char *)&sa->sa_data[sa->sa_env_off],
1277 argc, (ssize_t)sa->sa_env_cnt);
1278 }
1279
1280 out:
1281 if (sp != NULL)
1282 kmem_free(sp, spsize);
1283 if (sa != NULL)
1284 kmem_free(sa, sasize);
1285 if (ksp != NULL) {
1286 if (ksp->ksp_reffds != NULL) {
1287 kmem_free(ksp->ksp_reffds,
1288 ksp->ksp_nreffds * sizeof (int));
1289 }
1290 kmem_free(ksp, sizeof (*ksp));
1291 }
1292
1293 if (err != 0)
1294 return ((int64_t)set_errno(err));
1295 return (ret);
1296 }
1297