11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  29  * Copyright 2018 Joyent, Inc.
  30  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  31  * Copyright 2022 Oxide Computer Company
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <sys/param.h>
  36 #include <sys/thread.h>
  37 #include <sys/sysmacros.h>
  38 #include <sys/signal.h>
  39 #include <sys/cred.h>
  40 #include <sys/priv.h>
  41 #include <sys/user.h>
  42 #include <sys/file.h>
  43 #include <sys/errno.h>
  44 #include <sys/vnode.h>
  45 #include <sys/mode.h>
  46 #include <sys/vfs.h>
  47 #include <sys/mman.h>
  48 #include <sys/kmem.h>
  49 #include <sys/proc.h>
  50 #include <sys/pathname.h>
  51 #include <sys/cmn_err.h>
 
 
 121         pcrp = kmem_alloc(size, KM_SLEEP);
 122         prgetcred(p, pcrp);
 123         if (pcrp->pr_ngroups != 0) {
 124                 v[0].p_filesz += sizeof (Note) + roundup(sizeof (prcred_t) +
 125                     sizeof (gid_t) * (pcrp->pr_ngroups - 1), sizeof (Word));
 126         } else {
 127                 v[0].p_filesz += sizeof (Note) +
 128                     roundup(sizeof (prcred_t), sizeof (Word));
 129         }
 130         kmem_free(pcrp, size);
 131 
 132 
 133 #if defined(__i386_COMPAT)
 134         mutex_enter(&p->p_ldtlock);
 135         size = prnldt(p) * sizeof (struct ssd);
 136         mutex_exit(&p->p_ldtlock);
 137         if (size != 0)
 138                 v[0].p_filesz += sizeof (Note) + roundup(size, sizeof (Word));
 139 #endif  /* __i386_COMPAT */
 140 
 141         if ((size = prhasx(p)? prgetprxregsize(p) : 0) != 0)
 142                 v[0].p_filesz += nlwp * sizeof (Note)
 143                     + nlwp * roundup(size, sizeof (Word));
 144 
 145 #if defined(__sparc)
 146         /*
 147          * Figure out the number and sizes of register windows.
 148          */
 149         {
 150                 kthread_t *t = p->p_tlist;
 151                 do {
 152                         if ((size = prnwindows(ttolwp(t))) != 0) {
 153                                 size = sizeof (gwindows_t) -
 154                                     (SPARC_MAXREGWINDOW - size) *
 155                                     sizeof (struct rwindow);
 156                                 v[0].p_filesz += sizeof (Note) +
 157                                     roundup(size, sizeof (Word));
 158                         }
 159                 } while ((t = t->t_forw) != p->p_tlist);
 160         }
 161         /*
 
 180 {
 181         union {
 182                 psinfo_t        psinfo;
 183                 pstatus_t       pstatus;
 184                 lwpsinfo_t      lwpsinfo;
 185                 lwpstatus_t     lwpstatus;
 186 #if defined(__sparc)
 187                 gwindows_t      gwindows;
 188                 asrset_t        asrset;
 189 #endif /* __sparc */
 190                 char            xregs[1];
 191                 aux_entry_t     auxv[__KERN_NAUXV_IMPL];
 192                 prcred_t        pcred;
 193                 prpriv_t        ppriv;
 194                 priv_impl_info_t prinfo;
 195                 struct utsname  uts;
 196                 prsecflags_t    psecflags;
 197                 prupanic_t      upanic;
 198         } *bigwad;
 199 
 200         size_t xregsize = prhasx(p)? prgetprxregsize(p) : 0;
 201         size_t crsize = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1);
 202         size_t psize = prgetprivsize();
 203         size_t bigsize = MAX(psize, MAX(sizeof (*bigwad),
 204             MAX(xregsize, crsize)));
 205 
 206         priv_impl_info_t *prii;
 207 
 208         lwpdir_t *ldp;
 209         lwpent_t *lep;
 210         kthread_t *t;
 211         klwp_t *lwp;
 212         user_t *up;
 213         int i;
 214         int nlwp;
 215         int nzomb;
 216         int error;
 217         uchar_t oldsig;
 218         uf_info_t *fip;
 219         int fd;
 220         vnode_t *vroot;
 
 557                                     size, (caddr_t)&bigwad->gwindows,
 558                                     rlimit, credp);
 559                                 if (error)
 560                                         goto done;
 561                         }
 562                 }
 563                 /*
 564                  * Ancillary State Registers.
 565                  */
 566                 if (p->p_model == DATAMODEL_LP64) {
 567                         prgetasregs(lwp, bigwad->asrset);
 568                         error = elfnote(vp, &offset, NT_ASRS,
 569                             sizeof (asrset_t), (caddr_t)bigwad->asrset,
 570                             rlimit, credp);
 571                         if (error)
 572                                 goto done;
 573                 }
 574 #endif /* __sparc */
 575 
 576                 if (xregsize) {
 577                         prgetprxregs(lwp, bigwad->xregs);
 578                         error = elfnote(vp, &offset, NT_PRXREG,
 579                             xregsize, bigwad->xregs, rlimit, credp);
 580                         if (error)
 581                                 goto done;
 582                 }
 583 
 584                 if (t->t_lwp->lwp_spymaster != NULL) {
 585                         void *psaddr = t->t_lwp->lwp_spymaster;
 586 #ifdef _ELF32_COMPAT
 587                         /*
 588                          * On a 64-bit kernel with 32-bit ELF compatibility,
 589                          * this file is compiled into two different objects:
 590                          * one is compiled normally, and the other is compiled
 591                          * with _ELF32_COMPAT set -- and therefore with a
 592                          * psinfo_t defined to be a psinfo32_t.  However, the
 593                          * psinfo_t denoting our spymaster is always of the
 594                          * native type; if we are in the _ELF32_COMPAT case,
 595                          * we need to explicitly convert it.
 596                          */
 597                         if (p->p_model == DATAMODEL_ILP32) {
 
 | 
 
 
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  29  * Copyright 2018 Joyent, Inc.
  30  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  31  * Copyright 2023 Oxide Computer Company
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <sys/param.h>
  36 #include <sys/thread.h>
  37 #include <sys/sysmacros.h>
  38 #include <sys/signal.h>
  39 #include <sys/cred.h>
  40 #include <sys/priv.h>
  41 #include <sys/user.h>
  42 #include <sys/file.h>
  43 #include <sys/errno.h>
  44 #include <sys/vnode.h>
  45 #include <sys/mode.h>
  46 #include <sys/vfs.h>
  47 #include <sys/mman.h>
  48 #include <sys/kmem.h>
  49 #include <sys/proc.h>
  50 #include <sys/pathname.h>
  51 #include <sys/cmn_err.h>
 
 
 121         pcrp = kmem_alloc(size, KM_SLEEP);
 122         prgetcred(p, pcrp);
 123         if (pcrp->pr_ngroups != 0) {
 124                 v[0].p_filesz += sizeof (Note) + roundup(sizeof (prcred_t) +
 125                     sizeof (gid_t) * (pcrp->pr_ngroups - 1), sizeof (Word));
 126         } else {
 127                 v[0].p_filesz += sizeof (Note) +
 128                     roundup(sizeof (prcred_t), sizeof (Word));
 129         }
 130         kmem_free(pcrp, size);
 131 
 132 
 133 #if defined(__i386_COMPAT)
 134         mutex_enter(&p->p_ldtlock);
 135         size = prnldt(p) * sizeof (struct ssd);
 136         mutex_exit(&p->p_ldtlock);
 137         if (size != 0)
 138                 v[0].p_filesz += sizeof (Note) + roundup(size, sizeof (Word));
 139 #endif  /* __i386_COMPAT */
 140 
 141         if ((size = prhasx(p) ? prgetprxregsize(p) : 0) != 0)
 142                 v[0].p_filesz += nlwp * sizeof (Note)
 143                     + nlwp * roundup(size, sizeof (Word));
 144 
 145 #if defined(__sparc)
 146         /*
 147          * Figure out the number and sizes of register windows.
 148          */
 149         {
 150                 kthread_t *t = p->p_tlist;
 151                 do {
 152                         if ((size = prnwindows(ttolwp(t))) != 0) {
 153                                 size = sizeof (gwindows_t) -
 154                                     (SPARC_MAXREGWINDOW - size) *
 155                                     sizeof (struct rwindow);
 156                                 v[0].p_filesz += sizeof (Note) +
 157                                     roundup(size, sizeof (Word));
 158                         }
 159                 } while ((t = t->t_forw) != p->p_tlist);
 160         }
 161         /*
 
 180 {
 181         union {
 182                 psinfo_t        psinfo;
 183                 pstatus_t       pstatus;
 184                 lwpsinfo_t      lwpsinfo;
 185                 lwpstatus_t     lwpstatus;
 186 #if defined(__sparc)
 187                 gwindows_t      gwindows;
 188                 asrset_t        asrset;
 189 #endif /* __sparc */
 190                 char            xregs[1];
 191                 aux_entry_t     auxv[__KERN_NAUXV_IMPL];
 192                 prcred_t        pcred;
 193                 prpriv_t        ppriv;
 194                 priv_impl_info_t prinfo;
 195                 struct utsname  uts;
 196                 prsecflags_t    psecflags;
 197                 prupanic_t      upanic;
 198         } *bigwad;
 199 
 200         size_t xregsize = prhasx(p) ? prgetprxregsize(p) : 0;
 201         size_t crsize = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1);
 202         size_t psize = prgetprivsize();
 203         size_t bigsize = MAX(psize, MAX(sizeof (*bigwad),
 204             MAX(xregsize, crsize)));
 205 
 206         priv_impl_info_t *prii;
 207 
 208         lwpdir_t *ldp;
 209         lwpent_t *lep;
 210         kthread_t *t;
 211         klwp_t *lwp;
 212         user_t *up;
 213         int i;
 214         int nlwp;
 215         int nzomb;
 216         int error;
 217         uchar_t oldsig;
 218         uf_info_t *fip;
 219         int fd;
 220         vnode_t *vroot;
 
 557                                     size, (caddr_t)&bigwad->gwindows,
 558                                     rlimit, credp);
 559                                 if (error)
 560                                         goto done;
 561                         }
 562                 }
 563                 /*
 564                  * Ancillary State Registers.
 565                  */
 566                 if (p->p_model == DATAMODEL_LP64) {
 567                         prgetasregs(lwp, bigwad->asrset);
 568                         error = elfnote(vp, &offset, NT_ASRS,
 569                             sizeof (asrset_t), (caddr_t)bigwad->asrset,
 570                             rlimit, credp);
 571                         if (error)
 572                                 goto done;
 573                 }
 574 #endif /* __sparc */
 575 
 576                 if (xregsize) {
 577                         prgetprxregs(lwp, (prxregset_t *)bigwad->xregs);
 578                         error = elfnote(vp, &offset, NT_PRXREG,
 579                             xregsize, bigwad->xregs, rlimit, credp);
 580                         if (error)
 581                                 goto done;
 582                 }
 583 
 584                 if (t->t_lwp->lwp_spymaster != NULL) {
 585                         void *psaddr = t->t_lwp->lwp_spymaster;
 586 #ifdef _ELF32_COMPAT
 587                         /*
 588                          * On a 64-bit kernel with 32-bit ELF compatibility,
 589                          * this file is compiled into two different objects:
 590                          * one is compiled normally, and the other is compiled
 591                          * with _ELF32_COMPAT set -- and therefore with a
 592                          * psinfo_t defined to be a psinfo32_t.  However, the
 593                          * psinfo_t denoting our spymaster is always of the
 594                          * native type; if we are in the _ELF32_COMPAT case,
 595                          * we need to explicitly convert it.
 596                          */
 597                         if (p->p_model == DATAMODEL_ILP32) {
 
 |