8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
29 * Copyright 2023 Oxide Computer Company
30 */
31
32 #include <sys/types.h>
33 #include <sys/uio.h>
34 #include <sys/param.h>
35 #include <sys/cmn_err.h>
36 #include <sys/cred.h>
37 #include <sys/policy.h>
38 #include <sys/debug.h>
39 #include <sys/errno.h>
40 #include <sys/file.h>
41 #include <sys/inline.h>
42 #include <sys/kmem.h>
43 #include <sys/proc.h>
44 #include <sys/brand.h>
45 #include <sys/regset.h>
46 #include <sys/sysmacros.h>
47 #include <sys/systm.h>
48 #include <sys/vfs.h>
1595 (sig == SIGSTOP || !p->p_pgidp->pid_pgorphaned))
1596 p->p_flag &= ~SSCONT;
1597 sigdelq(p, NULL, SIGCONT);
1598 sigdelset(&p->p_sig, SIGCONT);
1599 sigdelset(&p->p_extsig, SIGCONT);
1600 if ((tx = p->p_tlist) != NULL) {
1601 do {
1602 sigdelq(p, tx, SIGCONT);
1603 sigdelset(&tx->t_sig, SIGCONT);
1604 sigdelset(&tx->t_extsig, SIGCONT);
1605 } while ((tx = tx->t_forw) != p->p_tlist);
1606 }
1607 }
1608 thread_lock(t);
1609 if (ISWAKEABLE(t) || ISWAITING(t)) {
1610 /* Set signaled sleeping/waiting lwp running */
1611 setrun_locked(t);
1612 } else if (t->t_state == TS_STOPPED && sig == SIGKILL) {
1613 /* If SIGKILL, set stopped lwp running */
1614 p->p_stopsig = 0;
1615 t->t_schedflag |= TS_XSTART | TS_PSTART;
1616 t->t_dtrace_stop = 0;
1617 setrun_locked(t);
1618 }
1619 t->t_sig_check = 1; /* so ISSIG will be done */
1620 thread_unlock(t);
1621 /*
1622 * More jobcontrol side-effects.
1623 */
1624 if (sig == SIGCONT && (tx = p->p_tlist) != NULL) {
1625 p->p_stopsig = 0;
1626 do {
1627 thread_lock(tx);
1628 if (tx->t_state == TS_STOPPED &&
1629 tx->t_whystop == PR_JOBCONTROL) {
1630 tx->t_schedflag |= TS_XSTART;
1631 setrun_locked(tx);
1632 }
1633 thread_unlock(tx);
1634 } while ((tx = tx->t_forw) != p->p_tlist);
1635 }
2369 }
2370
2371 /*
2372 * Change process credentials to specified zone. Used to temporarily
2373 * set a process to run in the global zone; only transitions between
2374 * the process's actual zone and the global zone are allowed.
2375 */
2376 static int
2377 pr_szoneid(proc_t *p, zoneid_t zoneid, cred_t *cr)
2378 {
2379 kthread_t *t;
2380 cred_t *oldcred;
2381 cred_t *newcred;
2382 zone_t *zptr;
2383 zoneid_t oldzoneid;
2384
2385 if (secpolicy_zone_config(cr) != 0)
2386 return (EPERM);
2387 if (zoneid != GLOBAL_ZONEID && zoneid != p->p_zone->zone_id)
2388 return (EINVAL);
2389 if ((zptr = zone_find_by_id(zoneid)) == NULL)
2390 return (EINVAL);
2391 mutex_exit(&p->p_lock);
2392 mutex_enter(&p->p_crlock);
2393 oldcred = p->p_cred;
2394 crhold(oldcred);
2395 mutex_exit(&p->p_crlock);
2396 newcred = crdup(oldcred);
2397 oldzoneid = crgetzoneid(oldcred);
2398 crfree(oldcred);
2399
2400 crsetzone(newcred, zptr);
2401 zone_rele(zptr);
2402
2403 mutex_enter(&p->p_crlock);
2404 oldcred = p->p_cred;
2405 p->p_cred = newcred;
2406 mutex_exit(&p->p_crlock);
2407 crfree(oldcred);
2408
2409 /*
2410 * The target process is changing zones (according to its cred), so
2411 * update the per-zone upcounts, which are based on process creds.
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright 2015, Joyent, Inc.
29 * Copyright 2023 Oxide Computer Company
30 */
31
32 #include <sys/types.h>
33 #include <sys/uio.h>
34 #include <sys/param.h>
35 #include <sys/cmn_err.h>
36 #include <sys/cred.h>
37 #include <sys/policy.h>
38 #include <sys/debug.h>
39 #include <sys/errno.h>
40 #include <sys/file.h>
41 #include <sys/inline.h>
42 #include <sys/kmem.h>
43 #include <sys/proc.h>
44 #include <sys/brand.h>
45 #include <sys/regset.h>
46 #include <sys/sysmacros.h>
47 #include <sys/systm.h>
48 #include <sys/vfs.h>
1595 (sig == SIGSTOP || !p->p_pgidp->pid_pgorphaned))
1596 p->p_flag &= ~SSCONT;
1597 sigdelq(p, NULL, SIGCONT);
1598 sigdelset(&p->p_sig, SIGCONT);
1599 sigdelset(&p->p_extsig, SIGCONT);
1600 if ((tx = p->p_tlist) != NULL) {
1601 do {
1602 sigdelq(p, tx, SIGCONT);
1603 sigdelset(&tx->t_sig, SIGCONT);
1604 sigdelset(&tx->t_extsig, SIGCONT);
1605 } while ((tx = tx->t_forw) != p->p_tlist);
1606 }
1607 }
1608 thread_lock(t);
1609 if (ISWAKEABLE(t) || ISWAITING(t)) {
1610 /* Set signaled sleeping/waiting lwp running */
1611 setrun_locked(t);
1612 } else if (t->t_state == TS_STOPPED && sig == SIGKILL) {
1613 /* If SIGKILL, set stopped lwp running */
1614 p->p_stopsig = 0;
1615 t->t_schedflag |= TS_XSTART | TS_PSTART | TS_BSTART;
1616 t->t_dtrace_stop = 0;
1617 setrun_locked(t);
1618 }
1619 t->t_sig_check = 1; /* so ISSIG will be done */
1620 thread_unlock(t);
1621 /*
1622 * More jobcontrol side-effects.
1623 */
1624 if (sig == SIGCONT && (tx = p->p_tlist) != NULL) {
1625 p->p_stopsig = 0;
1626 do {
1627 thread_lock(tx);
1628 if (tx->t_state == TS_STOPPED &&
1629 tx->t_whystop == PR_JOBCONTROL) {
1630 tx->t_schedflag |= TS_XSTART;
1631 setrun_locked(tx);
1632 }
1633 thread_unlock(tx);
1634 } while ((tx = tx->t_forw) != p->p_tlist);
1635 }
2369 }
2370
2371 /*
2372 * Change process credentials to specified zone. Used to temporarily
2373 * set a process to run in the global zone; only transitions between
2374 * the process's actual zone and the global zone are allowed.
2375 */
2376 static int
2377 pr_szoneid(proc_t *p, zoneid_t zoneid, cred_t *cr)
2378 {
2379 kthread_t *t;
2380 cred_t *oldcred;
2381 cred_t *newcred;
2382 zone_t *zptr;
2383 zoneid_t oldzoneid;
2384
2385 if (secpolicy_zone_config(cr) != 0)
2386 return (EPERM);
2387 if (zoneid != GLOBAL_ZONEID && zoneid != p->p_zone->zone_id)
2388 return (EINVAL);
2389 /*
2390 * We cannot hold p_lock when we call zone_find_by_id since that can
2391 * lead to a deadlock. zone_find_by_id() takes zonehash_lock.
2392 * zone_enter() can hold the zonehash_lock and needs p_lock when it
2393 * calls task_join.
2394 */
2395 mutex_exit(&p->p_lock);
2396 if ((zptr = zone_find_by_id(zoneid)) == NULL) {
2397 mutex_enter(&p->p_lock);
2398 return (EINVAL);
2399 }
2400 mutex_enter(&p->p_crlock);
2401 oldcred = p->p_cred;
2402 crhold(oldcred);
2403 mutex_exit(&p->p_crlock);
2404 newcred = crdup(oldcred);
2405 oldzoneid = crgetzoneid(oldcred);
2406 crfree(oldcred);
2407
2408 crsetzone(newcred, zptr);
2409 zone_rele(zptr);
2410
2411 mutex_enter(&p->p_crlock);
2412 oldcred = p->p_cred;
2413 p->p_cred = newcred;
2414 mutex_exit(&p->p_crlock);
2415 crfree(oldcred);
2416
2417 /*
2418 * The target process is changing zones (according to its cred), so
2419 * update the per-zone upcounts, which are based on process creds.
|