Print this page




   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.