Print this page
    
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/exec/elf/elf_notes.c
          +++ new/usr/src/uts/common/exec/elf/elf_notes.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License, Version 1.0 only
   6    6   * (the "License").  You may not use this file except in compliance
   7    7   * with the License.
   8    8   *
   9    9   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10   10   * or http://www.opensolaris.org/os/licensing.
  11   11   * See the License for the specific language governing permissions
  12   12   * and limitations under the License.
  13   13   *
  14   14   * When distributing Covered Code, include this CDDL HEADER in each
  15   15   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   16   * If applicable, add the following below this CDDL HEADER, with the
  17   17   * fields enclosed by brackets "[]" replaced with your own identifying
  18   18   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   19   *
  20   20   * CDDL HEADER END
  21   21   */
  22   22  /*
  23   23   * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27   27  /*
  28   28   * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  29   29   * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  30   30   */
  31   31  
  32   32  #include <sys/types.h>
  33   33  #include <sys/param.h>
  34   34  #include <sys/thread.h>
  35   35  #include <sys/sysmacros.h>
  36   36  #include <sys/signal.h>
  37   37  #include <sys/cred.h>
  38   38  #include <sys/priv.h>
  39   39  #include <sys/user.h>
  40   40  #include <sys/file.h>
  41   41  #include <sys/errno.h>
  42   42  #include <sys/vnode.h>
  43   43  #include <sys/mode.h>
  44   44  #include <sys/vfs.h>
  45   45  #include <sys/mman.h>
  46   46  #include <sys/kmem.h>
  47   47  #include <sys/proc.h>
  48   48  #include <sys/pathname.h>
  49   49  #include <sys/cmn_err.h>
  50   50  #include <sys/systm.h>
  51   51  #include <sys/elf.h>
  52   52  #include <sys/vmsystm.h>
  53   53  #include <sys/debug.h>
  54   54  #include <sys/procfs.h>
  55   55  #include <sys/regset.h>
  56   56  #include <sys/auxv.h>
  57   57  #include <sys/exec.h>
  58   58  #include <sys/prsystm.h>
  59   59  #include <sys/utsname.h>
  60   60  #include <sys/zone.h>
  61   61  #include <vm/as.h>
  62   62  #include <vm/rm.h>
  63   63  #include <sys/modctl.h>
  64   64  #include <sys/systeminfo.h>
  65   65  #include <sys/machelf.h>
  66   66  #include <sys/sunddi.h>
  67   67  #include "elf_impl.h"
  68   68  #if defined(__i386) || defined(__i386_COMPAT)
  69   69  #include <sys/sysi86.h>
  70   70  #endif
  71   71  
  72   72  void
  73   73  setup_note_header(Phdr *v, proc_t *p)
  74   74  {
  75   75          int nlwp = p->p_lwpcnt;
  76   76          int nzomb = p->p_zombcnt;
  77   77          int nfd;
  78   78          size_t size;
  79   79          prcred_t *pcrp;
  80   80          uf_info_t *fip;
  81   81          uf_entry_t *ufp;
  82   82          int fd;
  83   83  
  84   84          fip = P_FINFO(p);
  85   85          nfd = 0;
  86   86          mutex_enter(&fip->fi_lock);
  
    | 
      ↓ open down ↓ | 
    86 lines elided | 
    
      ↑ open up ↑ | 
  
  87   87          for (fd = 0; fd < fip->fi_nfiles; fd++) {
  88   88                  UF_ENTER(ufp, fip, fd);
  89   89                  if ((ufp->uf_file != NULL) && (ufp->uf_file->f_count > 0))
  90   90                          nfd++;
  91   91                  UF_EXIT(ufp);
  92   92          }
  93   93          mutex_exit(&fip->fi_lock);
  94   94  
  95   95          v[0].p_type = PT_NOTE;
  96   96          v[0].p_flags = PF_R;
  97      -        v[0].p_filesz = (sizeof (Note) * (9 + 2 * nlwp + nzomb + nfd))
       97 +        v[0].p_filesz = (sizeof (Note) * (10 + 2 * nlwp + nzomb + nfd))
  98   98              + roundup(sizeof (psinfo_t), sizeof (Word))
  99   99              + roundup(sizeof (pstatus_t), sizeof (Word))
 100  100              + roundup(prgetprivsize(), sizeof (Word))
 101  101              + roundup(priv_get_implinfo_size(), sizeof (Word))
 102  102              + roundup(strlen(platform) + 1, sizeof (Word))
 103  103              + roundup(strlen(p->p_zone->zone_name) + 1, sizeof (Word))
 104  104              + roundup(__KERN_NAUXV_IMPL * sizeof (aux_entry_t), sizeof (Word))
 105  105              + roundup(sizeof (utsname), sizeof (Word))
 106  106              + roundup(sizeof (core_content_t), sizeof (Word))
      107 +            + roundup(sizeof (prsecflags_t), sizeof (Word))
 107  108              + (nlwp + nzomb) * roundup(sizeof (lwpsinfo_t), sizeof (Word))
 108  109              + nlwp * roundup(sizeof (lwpstatus_t), sizeof (Word))
 109  110              + nfd * roundup(sizeof (prfdinfo_t), sizeof (Word));
 110  111  
 111  112          if (curproc->p_agenttp != NULL) {
 112  113                  v[0].p_filesz += sizeof (Note) +
 113  114                      roundup(sizeof (psinfo_t), sizeof (Word));
 114  115          }
 115  116  
 116  117          size = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1);
 117  118          pcrp = kmem_alloc(size, KM_SLEEP);
 118  119          prgetcred(p, pcrp);
 119  120          if (pcrp->pr_ngroups != 0) {
 120  121                  v[0].p_filesz += sizeof (Note) + roundup(sizeof (prcred_t) +
 121  122                      sizeof (gid_t) * (pcrp->pr_ngroups - 1), sizeof (Word));
 122  123          } else {
 123  124                  v[0].p_filesz += sizeof (Note) +
 124  125                      roundup(sizeof (prcred_t), sizeof (Word));
 125  126          }
 126  127          kmem_free(pcrp, size);
 127  128  
 128  129  
 129  130  #if defined(__i386) || defined(__i386_COMPAT)
 130  131          mutex_enter(&p->p_ldtlock);
 131  132          size = prnldt(p) * sizeof (struct ssd);
 132  133          mutex_exit(&p->p_ldtlock);
 133  134          if (size != 0)
 134  135                  v[0].p_filesz += sizeof (Note) + roundup(size, sizeof (Word));
 135  136  #endif  /* __i386 || __i386_COMPAT */
 136  137  
 137  138          if ((size = prhasx(p)? prgetprxregsize(p) : 0) != 0)
 138  139                  v[0].p_filesz += nlwp * sizeof (Note)
 139  140                      + nlwp * roundup(size, sizeof (Word));
 140  141  
 141  142  #if defined(__sparc)
 142  143          /*
 143  144           * Figure out the number and sizes of register windows.
 144  145           */
 145  146          {
 146  147                  kthread_t *t = p->p_tlist;
 147  148                  do {
 148  149                          if ((size = prnwindows(ttolwp(t))) != 0) {
 149  150                                  size = sizeof (gwindows_t) -
 150  151                                      (SPARC_MAXREGWINDOW - size) *
 151  152                                      sizeof (struct rwindow);
 152  153                                  v[0].p_filesz += sizeof (Note) +
 153  154                                      roundup(size, sizeof (Word));
 154  155                          }
 155  156                  } while ((t = t->t_forw) != p->p_tlist);
 156  157          }
 157  158          /*
 158  159           * Space for the Ancillary State Registers.
 159  160           */
 160  161          if (p->p_model == DATAMODEL_LP64)
 161  162                  v[0].p_filesz += nlwp * sizeof (Note)
 162  163                      + nlwp * roundup(sizeof (asrset_t), sizeof (Word));
 163  164  #endif /* __sparc */
 164  165  }
 165  166  
 166  167  int
 167  168  write_elfnotes(proc_t *p, int sig, vnode_t *vp, offset_t offset,
 168  169      rlim64_t rlimit, cred_t *credp, core_content_t content)
 169  170  {
 170  171          union {
 171  172                  psinfo_t        psinfo;
 172  173                  pstatus_t       pstatus;
 173  174                  lwpsinfo_t      lwpsinfo;
 174  175                  lwpstatus_t     lwpstatus;
  
    | 
      ↓ open down ↓ | 
    58 lines elided | 
    
      ↑ open up ↑ | 
  
 175  176  #if defined(__sparc)
 176  177                  gwindows_t      gwindows;
 177  178                  asrset_t        asrset;
 178  179  #endif /* __sparc */
 179  180                  char            xregs[1];
 180  181                  aux_entry_t     auxv[__KERN_NAUXV_IMPL];
 181  182                  prcred_t        pcred;
 182  183                  prpriv_t        ppriv;
 183  184                  priv_impl_info_t prinfo;
 184  185                  struct utsname  uts;
      186 +                prsecflags_t    psecflags;
 185  187          } *bigwad;
 186  188  
 187  189          size_t xregsize = prhasx(p)? prgetprxregsize(p) : 0;
 188  190          size_t crsize = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1);
 189  191          size_t psize = prgetprivsize();
 190  192          size_t bigsize = MAX(psize, MAX(sizeof (*bigwad),
 191  193              MAX(xregsize, crsize)));
 192  194  
 193  195          priv_impl_info_t *prii;
 194  196  
 195  197          lwpdir_t *ldp;
 196  198          lwpent_t *lep;
 197  199          kthread_t *t;
 198  200          klwp_t *lwp;
 199  201          user_t *up;
 200  202          int i;
 201  203          int nlwp;
 202  204          int nzomb;
 203  205          int error;
 204  206          uchar_t oldsig;
 205  207          uf_info_t *fip;
 206  208          int fd;
 207  209          vnode_t *vroot;
 208  210  
 209  211  #if defined(__i386) || defined(__i386_COMPAT)
 210  212          struct ssd *ssd;
 211  213          size_t ssdsize;
 212  214  #endif  /* __i386 || __i386_COMPAT */
 213  215  
 214  216          bigsize = MAX(bigsize, priv_get_implinfo_size());
 215  217  
 216  218          bigwad = kmem_alloc(bigsize, KM_SLEEP);
 217  219  
 218  220          /*
 219  221           * The order of the elfnote entries should be same here
 220  222           * and in the gcore(1) command.  Synchronization is
 221  223           * needed between the kernel and gcore(1).
 222  224           */
 223  225  
 224  226          /*
 225  227           * Get the psinfo, and set the wait status to indicate that a core was
 226  228           * dumped.  We have to forge this since p->p_wcode is not set yet.
 227  229           */
 228  230          mutex_enter(&p->p_lock);
 229  231          prgetpsinfo(p, &bigwad->psinfo);
 230  232          mutex_exit(&p->p_lock);
 231  233          bigwad->psinfo.pr_wstat = wstat(CLD_DUMPED, sig);
 232  234  
 233  235          error = elfnote(vp, &offset, NT_PSINFO, sizeof (bigwad->psinfo),
 234  236              (caddr_t)&bigwad->psinfo, rlimit, credp);
 235  237          if (error)
 236  238                  goto done;
 237  239  
 238  240          /*
 239  241           * Modify t_whystop and lwp_cursig so it appears that the current LWP
 240  242           * is stopped after faulting on the signal that caused the core dump.
 241  243           * As a result, prgetstatus() will record that signal, the saved
 242  244           * lwp_siginfo, and its signal handler in the core file status.  We
 243  245           * restore lwp_cursig in case a subsequent signal was received while
 244  246           * dumping core.
 245  247           */
 246  248          mutex_enter(&p->p_lock);
 247  249          lwp = ttolwp(curthread);
 248  250  
 249  251          oldsig = lwp->lwp_cursig;
 250  252          lwp->lwp_cursig = (uchar_t)sig;
 251  253          curthread->t_whystop = PR_FAULTED;
 252  254  
 253  255          prgetstatus(p, &bigwad->pstatus, p->p_zone);
 254  256          bigwad->pstatus.pr_lwp.pr_why = 0;
 255  257  
 256  258          curthread->t_whystop = 0;
 257  259          lwp->lwp_cursig = oldsig;
 258  260          mutex_exit(&p->p_lock);
 259  261  
 260  262          error = elfnote(vp, &offset, NT_PSTATUS, sizeof (bigwad->pstatus),
 261  263              (caddr_t)&bigwad->pstatus, rlimit, credp);
 262  264          if (error)
 263  265                  goto done;
 264  266  
 265  267          error = elfnote(vp, &offset, NT_PLATFORM, strlen(platform) + 1,
 266  268              platform, rlimit, credp);
 267  269          if (error)
 268  270                  goto done;
 269  271  
 270  272          up = PTOU(p);
 271  273          for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
 272  274                  bigwad->auxv[i].a_type = up->u_auxv[i].a_type;
 273  275                  bigwad->auxv[i].a_un.a_val = up->u_auxv[i].a_un.a_val;
 274  276          }
 275  277          error = elfnote(vp, &offset, NT_AUXV, sizeof (bigwad->auxv),
 276  278              (caddr_t)bigwad->auxv, rlimit, credp);
 277  279          if (error)
 278  280                  goto done;
 279  281  
  
    | 
      ↓ open down ↓ | 
    85 lines elided | 
    
      ↑ open up ↑ | 
  
 280  282          bcopy(&utsname, &bigwad->uts, sizeof (struct utsname));
 281  283          if (!INGLOBALZONE(p)) {
 282  284                  bcopy(p->p_zone->zone_nodename, &bigwad->uts.nodename,
 283  285                      _SYS_NMLN);
 284  286          }
 285  287          error = elfnote(vp, &offset, NT_UTSNAME, sizeof (struct utsname),
 286  288              (caddr_t)&bigwad->uts, rlimit, credp);
 287  289          if (error)
 288  290                  goto done;
 289  291  
      292 +        prgetsecflags(p, &bigwad->psecflags);
      293 +        error = elfnote(vp, &offset, NT_SECFLAGS, sizeof (prsecflags_t),
      294 +            (caddr_t)&bigwad->psecflags, rlimit, credp);
      295 +        if (error)
      296 +                goto done;
      297 +
 290  298          prgetcred(p, &bigwad->pcred);
 291  299  
 292  300          if (bigwad->pcred.pr_ngroups != 0) {
 293  301                  crsize = sizeof (prcred_t) +
 294  302                      sizeof (gid_t) * (bigwad->pcred.pr_ngroups - 1);
 295  303          } else
 296  304                  crsize = sizeof (prcred_t);
 297  305  
 298  306          error = elfnote(vp, &offset, NT_PRCRED, crsize,
 299  307              (caddr_t)&bigwad->pcred, rlimit, credp);
 300  308          if (error)
 301  309                  goto done;
 302  310  
 303  311          error = elfnote(vp, &offset, NT_CONTENT, sizeof (core_content_t),
 304  312              (caddr_t)&content, rlimit, credp);
 305  313          if (error)
 306  314                  goto done;
 307  315  
 308  316          prgetpriv(p, &bigwad->ppriv);
 309  317  
 310  318          error = elfnote(vp, &offset, NT_PRPRIV, psize,
 311  319              (caddr_t)&bigwad->ppriv, rlimit, credp);
 312  320          if (error)
 313  321                  goto done;
 314  322  
 315  323          prii = priv_hold_implinfo();
 316  324          error = elfnote(vp, &offset, NT_PRPRIVINFO, priv_get_implinfo_size(),
 317  325              (caddr_t)prii, rlimit, credp);
 318  326          priv_release_implinfo();
 319  327          if (error)
 320  328                  goto done;
 321  329  
 322  330          /* zone can't go away as long as process exists */
 323  331          error = elfnote(vp, &offset, NT_ZONENAME,
 324  332              strlen(p->p_zone->zone_name) + 1, p->p_zone->zone_name,
 325  333              rlimit, credp);
 326  334          if (error)
 327  335                  goto done;
 328  336  
 329  337  
 330  338          /* open file table */
 331  339          vroot = PTOU(p)->u_rdir;
 332  340          if (vroot == NULL)
 333  341                  vroot = rootdir;
 334  342  
 335  343          VN_HOLD(vroot);
 336  344  
 337  345          fip = P_FINFO(p);
 338  346  
 339  347          for (fd = 0; fd < fip->fi_nfiles; fd++) {
 340  348                  uf_entry_t *ufp;
 341  349                  vnode_t *fvp;
 342  350                  struct file *fp;
 343  351                  vattr_t vattr;
 344  352                  prfdinfo_t fdinfo;
 345  353  
 346  354                  bzero(&fdinfo, sizeof (fdinfo));
 347  355  
 348  356                  mutex_enter(&fip->fi_lock);
 349  357                  UF_ENTER(ufp, fip, fd);
 350  358                  if (((fp = ufp->uf_file) == NULL) || (fp->f_count < 1)) {
 351  359                          UF_EXIT(ufp);
 352  360                          mutex_exit(&fip->fi_lock);
 353  361                          continue;
 354  362                  }
 355  363  
 356  364                  fdinfo.pr_fd = fd;
 357  365                  fdinfo.pr_fdflags = ufp->uf_flag;
 358  366                  fdinfo.pr_fileflags = fp->f_flag2;
 359  367                  fdinfo.pr_fileflags <<= 16;
 360  368                  fdinfo.pr_fileflags |= fp->f_flag;
 361  369                  if ((fdinfo.pr_fileflags & (FSEARCH | FEXEC)) == 0)
 362  370                          fdinfo.pr_fileflags += FOPEN;
 363  371                  fdinfo.pr_offset = fp->f_offset;
 364  372  
 365  373  
 366  374                  fvp = fp->f_vnode;
 367  375                  VN_HOLD(fvp);
 368  376                  UF_EXIT(ufp);
 369  377                  mutex_exit(&fip->fi_lock);
 370  378  
 371  379                  /*
 372  380                   * There are some vnodes that have no corresponding
 373  381                   * path.  Its reasonable for this to fail, in which
 374  382                   * case the path will remain an empty string.
 375  383                   */
 376  384                  (void) vnodetopath(vroot, fvp, fdinfo.pr_path,
 377  385                      sizeof (fdinfo.pr_path), credp);
 378  386  
 379  387                  if (VOP_GETATTR(fvp, &vattr, 0, credp, NULL) != 0) {
 380  388                          /*
 381  389                           * Try to write at least a subset of information
 382  390                           */
 383  391                          fdinfo.pr_major = 0;
 384  392                          fdinfo.pr_minor = 0;
 385  393                          fdinfo.pr_ino = 0;
 386  394                          fdinfo.pr_mode = 0;
 387  395                          fdinfo.pr_uid = (uid_t)-1;
 388  396                          fdinfo.pr_gid = (gid_t)-1;
 389  397                          fdinfo.pr_rmajor = 0;
 390  398                          fdinfo.pr_rminor = 0;
 391  399                          fdinfo.pr_size = -1;
 392  400  
 393  401                          error = elfnote(vp, &offset, NT_FDINFO,
 394  402                              sizeof (fdinfo), &fdinfo, rlimit, credp);
 395  403                          VN_RELE(fvp);
 396  404                          VN_RELE(vroot);
 397  405                          if (error)
 398  406                                  goto done;
 399  407                          continue;
 400  408                  }
 401  409  
 402  410                  if (fvp->v_type == VSOCK)
 403  411                          fdinfo.pr_fileflags |= sock_getfasync(fvp);
 404  412  
 405  413                  VN_RELE(fvp);
 406  414  
 407  415                  /*
 408  416                   * This logic mirrors fstat(), which we cannot use
 409  417                   * directly, as it calls copyout().
 410  418                   */
 411  419                  fdinfo.pr_major = getmajor(vattr.va_fsid);
 412  420                  fdinfo.pr_minor = getminor(vattr.va_fsid);
 413  421                  fdinfo.pr_ino = (ino64_t)vattr.va_nodeid;
 414  422                  fdinfo.pr_mode = VTTOIF(vattr.va_type) | vattr.va_mode;
 415  423                  fdinfo.pr_uid = vattr.va_uid;
 416  424                  fdinfo.pr_gid = vattr.va_gid;
 417  425                  fdinfo.pr_rmajor = getmajor(vattr.va_rdev);
 418  426                  fdinfo.pr_rminor = getminor(vattr.va_rdev);
 419  427                  fdinfo.pr_size = (off64_t)vattr.va_size;
 420  428  
 421  429                  error = elfnote(vp, &offset, NT_FDINFO,
 422  430                      sizeof (fdinfo), &fdinfo, rlimit, credp);
 423  431                  if (error) {
 424  432                          VN_RELE(vroot);
 425  433                          goto done;
 426  434                  }
 427  435          }
 428  436  
 429  437          VN_RELE(vroot);
 430  438  
 431  439  #if defined(__i386) || defined(__i386_COMPAT)
 432  440          mutex_enter(&p->p_ldtlock);
 433  441          ssdsize = prnldt(p) * sizeof (struct ssd);
 434  442          if (ssdsize != 0) {
 435  443                  ssd = kmem_alloc(ssdsize, KM_SLEEP);
 436  444                  prgetldt(p, ssd);
 437  445                  error = elfnote(vp, &offset, NT_LDT, ssdsize,
 438  446                      (caddr_t)ssd, rlimit, credp);
 439  447                  kmem_free(ssd, ssdsize);
 440  448          }
 441  449          mutex_exit(&p->p_ldtlock);
 442  450          if (error)
 443  451                  goto done;
 444  452  #endif  /* __i386 || defined(__i386_COMPAT) */
 445  453  
 446  454          nlwp = p->p_lwpcnt;
 447  455          nzomb = p->p_zombcnt;
 448  456          /* for each entry in the lwp directory ... */
 449  457          for (ldp = p->p_lwpdir; nlwp + nzomb != 0; ldp++) {
 450  458  
 451  459                  if ((lep = ldp->ld_entry) == NULL)      /* empty slot */
 452  460                          continue;
 453  461  
 454  462                  if ((t = lep->le_thread) != NULL) {     /* active lwp */
 455  463                          ASSERT(nlwp != 0);
 456  464                          nlwp--;
 457  465                          lwp = ttolwp(t);
 458  466                          mutex_enter(&p->p_lock);
 459  467                          prgetlwpsinfo(t, &bigwad->lwpsinfo);
 460  468                          mutex_exit(&p->p_lock);
 461  469                  } else {                                /* zombie lwp */
 462  470                          ASSERT(nzomb != 0);
 463  471                          nzomb--;
 464  472                          bzero(&bigwad->lwpsinfo, sizeof (bigwad->lwpsinfo));
 465  473                          bigwad->lwpsinfo.pr_lwpid = lep->le_lwpid;
 466  474                          bigwad->lwpsinfo.pr_state = SZOMB;
 467  475                          bigwad->lwpsinfo.pr_sname = 'Z';
 468  476                          bigwad->lwpsinfo.pr_start.tv_sec = lep->le_start;
 469  477                  }
 470  478                  error = elfnote(vp, &offset, NT_LWPSINFO,
 471  479                      sizeof (bigwad->lwpsinfo), (caddr_t)&bigwad->lwpsinfo,
 472  480                      rlimit, credp);
 473  481                  if (error)
 474  482                          goto done;
 475  483                  if (t == NULL)          /* nothing more to do for a zombie */
 476  484                          continue;
 477  485  
 478  486                  mutex_enter(&p->p_lock);
 479  487                  if (t == curthread) {
 480  488                          /*
 481  489                           * Modify t_whystop and lwp_cursig so it appears that
 482  490                           * the current LWP is stopped after faulting on the
 483  491                           * signal that caused the core dump.  As a result,
 484  492                           * prgetlwpstatus() will record that signal, the saved
 485  493                           * lwp_siginfo, and its signal handler in the core file
 486  494                           * status.  We restore lwp_cursig in case a subsequent
 487  495                           * signal was received while dumping core.
 488  496                           */
 489  497                          oldsig = lwp->lwp_cursig;
 490  498                          lwp->lwp_cursig = (uchar_t)sig;
 491  499                          t->t_whystop = PR_FAULTED;
 492  500  
 493  501                          prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone);
 494  502                          bigwad->lwpstatus.pr_why = 0;
 495  503  
 496  504                          t->t_whystop = 0;
 497  505                          lwp->lwp_cursig = oldsig;
 498  506                  } else {
 499  507                          prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone);
 500  508                  }
 501  509                  mutex_exit(&p->p_lock);
 502  510                  error = elfnote(vp, &offset, NT_LWPSTATUS,
 503  511                      sizeof (bigwad->lwpstatus), (caddr_t)&bigwad->lwpstatus,
 504  512                      rlimit, credp);
 505  513                  if (error)
 506  514                          goto done;
 507  515  
 508  516  #if defined(__sparc)
 509  517                  /*
 510  518                   * Unspilled SPARC register windows.
 511  519                   */
 512  520                  {
 513  521                          size_t size = prnwindows(lwp);
 514  522  
 515  523                          if (size != 0) {
 516  524                                  size = sizeof (gwindows_t) -
 517  525                                      (SPARC_MAXREGWINDOW - size) *
 518  526                                      sizeof (struct rwindow);
 519  527                                  prgetwindows(lwp, &bigwad->gwindows);
 520  528                                  error = elfnote(vp, &offset, NT_GWINDOWS,
 521  529                                      size, (caddr_t)&bigwad->gwindows,
 522  530                                      rlimit, credp);
 523  531                                  if (error)
 524  532                                          goto done;
 525  533                          }
 526  534                  }
 527  535                  /*
 528  536                   * Ancillary State Registers.
 529  537                   */
 530  538                  if (p->p_model == DATAMODEL_LP64) {
 531  539                          prgetasregs(lwp, bigwad->asrset);
 532  540                          error = elfnote(vp, &offset, NT_ASRS,
 533  541                              sizeof (asrset_t), (caddr_t)bigwad->asrset,
 534  542                              rlimit, credp);
 535  543                          if (error)
 536  544                                  goto done;
 537  545                  }
 538  546  #endif /* __sparc */
 539  547  
 540  548                  if (xregsize) {
 541  549                          prgetprxregs(lwp, bigwad->xregs);
 542  550                          error = elfnote(vp, &offset, NT_PRXREG,
 543  551                              xregsize, bigwad->xregs, rlimit, credp);
 544  552                          if (error)
 545  553                                  goto done;
 546  554                  }
 547  555  
 548  556                  if (t->t_lwp->lwp_spymaster != NULL) {
 549  557                          void *psaddr = t->t_lwp->lwp_spymaster;
 550  558  #ifdef _ELF32_COMPAT
 551  559                          /*
 552  560                           * On a 64-bit kernel with 32-bit ELF compatibility,
 553  561                           * this file is compiled into two different objects:
 554  562                           * one is compiled normally, and the other is compiled
 555  563                           * with _ELF32_COMPAT set -- and therefore with a
 556  564                           * psinfo_t defined to be a psinfo32_t.  However, the
 557  565                           * psinfo_t denoting our spymaster is always of the
 558  566                           * native type; if we are in the _ELF32_COMPAT case,
 559  567                           * we need to explicitly convert it.
 560  568                           */
 561  569                          if (p->p_model == DATAMODEL_ILP32) {
 562  570                                  psinfo_kto32(psaddr, &bigwad->psinfo);
 563  571                                  psaddr = &bigwad->psinfo;
 564  572                          }
 565  573  #endif
 566  574  
 567  575                          error = elfnote(vp, &offset, NT_SPYMASTER,
 568  576                              sizeof (psinfo_t), psaddr, rlimit, credp);
 569  577                          if (error)
 570  578                                  goto done;
 571  579                  }
 572  580          }
 573  581          ASSERT(nlwp == 0);
 574  582  
 575  583  done:
 576  584          kmem_free(bigwad, bigsize);
 577  585          return (error);
 578  586  }
  
    | 
      ↓ open down ↓ | 
    279 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX