Print this page
    
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/fs/proc/prvnops.c
          +++ new/usr/src/uts/common/fs/proc/prvnops.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 (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2015, Joyent, Inc.
  25   25   */
  26   26  
  27   27  /*      Copyright (c) 1984,      1986, 1987, 1988, 1989 AT&T    */
  28   28  /*        All Rights Reserved   */
  29   29  
  30   30  #include <sys/types.h>
  31   31  #include <sys/param.h>
  32   32  #include <sys/time.h>
  33   33  #include <sys/cred.h>
  34   34  #include <sys/policy.h>
  35   35  #include <sys/debug.h>
  36   36  #include <sys/dirent.h>
  37   37  #include <sys/errno.h>
  38   38  #include <sys/file.h>
  39   39  #include <sys/inline.h>
  40   40  #include <sys/kmem.h>
  41   41  #include <sys/pathname.h>
  42   42  #include <sys/proc.h>
  43   43  #include <sys/brand.h>
  44   44  #include <sys/signal.h>
  45   45  #include <sys/stat.h>
  46   46  #include <sys/sysmacros.h>
  47   47  #include <sys/systm.h>
  48   48  #include <sys/zone.h>
  49   49  #include <sys/uio.h>
  50   50  #include <sys/var.h>
  51   51  #include <sys/mode.h>
  52   52  #include <sys/poll.h>
  53   53  #include <sys/user.h>
  54   54  #include <sys/vfs.h>
  55   55  #include <sys/vfs_opreg.h>
  56   56  #include <sys/gfs.h>
  57   57  #include <sys/vnode.h>
  58   58  #include <sys/fault.h>
  59   59  #include <sys/syscall.h>
  60   60  #include <sys/procfs.h>
  61   61  #include <sys/atomic.h>
  62   62  #include <sys/cmn_err.h>
  63   63  #include <sys/contract_impl.h>
  64   64  #include <sys/ctfs.h>
  65   65  #include <sys/avl.h>
  66   66  #include <fs/fs_subr.h>
  67   67  #include <vm/rm.h>
  68   68  #include <vm/as.h>
  69   69  #include <vm/seg.h>
  70   70  #include <vm/seg_vn.h>
  71   71  #include <vm/hat.h>
  72   72  #include <fs/proc/prdata.h>
  73   73  #if defined(__sparc)
  74   74  #include <sys/regset.h>
  75   75  #endif
  76   76  #if defined(__x86)
  77   77  #include <sys/sysi86.h>
  78   78  #endif
  79   79  
  80   80  /*
  81   81   * Created by prinit.
  82   82   */
  83   83  vnodeops_t *prvnodeops;
  84   84  
  85   85  /*
  86   86   * Directory characteristics (patterned after the s5 file system).
  87   87   */
  88   88  #define PRROOTINO       2
  89   89  
  90   90  #define PRDIRSIZE       14
  91   91  struct prdirect {
  92   92          ushort_t        d_ino;
  93   93          char            d_name[PRDIRSIZE];
  94   94  };
  95   95  
  96   96  #define PRSDSIZE        (sizeof (struct prdirect))
  97   97  
  98   98  /*
  99   99   * Maximum length of the /proc/$$/argv file:
 100  100   */
 101  101  int prmaxargvlen = 4096;
 102  102  
 103  103  /*
 104  104   * Directory characteristics.
 105  105   */
 106  106  typedef struct prdirent {
 107  107          ino64_t         d_ino;          /* "inode number" of entry */
 108  108          off64_t         d_off;          /* offset of disk directory entry */
 109  109          unsigned short  d_reclen;       /* length of this record */
 110  110          char            d_name[14];     /* name of file */
 111  111  } prdirent_t;
 112  112  
 113  113  /*
 114  114   * Contents of a /proc/<pid> directory.
 115  115   * Reuse d_ino field for the /proc file type.
 116  116   */
 117  117  static prdirent_t piddir[] = {
 118  118          { PR_PIDDIR,     1 * sizeof (prdirent_t), sizeof (prdirent_t),
 119  119                  "." },
 120  120          { PR_PROCDIR,    2 * sizeof (prdirent_t), sizeof (prdirent_t),
 121  121                  ".." },
 122  122          { PR_AS,         3 * sizeof (prdirent_t), sizeof (prdirent_t),
 123  123                  "as" },
 124  124          { PR_CTL,        4 * sizeof (prdirent_t), sizeof (prdirent_t),
 125  125                  "ctl" },
 126  126          { PR_STATUS,     5 * sizeof (prdirent_t), sizeof (prdirent_t),
 127  127                  "status" },
 128  128          { PR_LSTATUS,    6 * sizeof (prdirent_t), sizeof (prdirent_t),
 129  129                  "lstatus" },
 130  130          { PR_PSINFO,     7 * sizeof (prdirent_t), sizeof (prdirent_t),
 131  131                  "psinfo" },
 132  132          { PR_LPSINFO,    8 * sizeof (prdirent_t), sizeof (prdirent_t),
 133  133                  "lpsinfo" },
 134  134          { PR_MAP,        9 * sizeof (prdirent_t), sizeof (prdirent_t),
 135  135                  "map" },
 136  136          { PR_RMAP,      10 * sizeof (prdirent_t), sizeof (prdirent_t),
 137  137                  "rmap" },
 138  138          { PR_XMAP,      11 * sizeof (prdirent_t), sizeof (prdirent_t),
 139  139                  "xmap" },
 140  140          { PR_CRED,      12 * sizeof (prdirent_t), sizeof (prdirent_t),
 141  141                  "cred" },
 142  142          { PR_SIGACT,    13 * sizeof (prdirent_t), sizeof (prdirent_t),
 143  143                  "sigact" },
 144  144          { PR_AUXV,      14 * sizeof (prdirent_t), sizeof (prdirent_t),
 145  145                  "auxv" },
 146  146          { PR_USAGE,     15 * sizeof (prdirent_t), sizeof (prdirent_t),
 147  147                  "usage" },
 148  148          { PR_LUSAGE,    16 * sizeof (prdirent_t), sizeof (prdirent_t),
 149  149                  "lusage" },
 150  150          { PR_PAGEDATA,  17 * sizeof (prdirent_t), sizeof (prdirent_t),
 151  151                  "pagedata" },
 152  152          { PR_WATCH,     18 * sizeof (prdirent_t), sizeof (prdirent_t),
 153  153                  "watch" },
 154  154          { PR_CURDIR,    19 * sizeof (prdirent_t), sizeof (prdirent_t),
 155  155                  "cwd" },
 156  156          { PR_ROOTDIR,   20 * sizeof (prdirent_t), sizeof (prdirent_t),
 157  157                  "root" },
 158  158          { PR_FDDIR,     21 * sizeof (prdirent_t), sizeof (prdirent_t),
 159  159                  "fd" },
 160  160          { PR_OBJECTDIR, 22 * sizeof (prdirent_t), sizeof (prdirent_t),
 161  161                  "object" },
 162  162          { PR_LWPDIR,    23 * sizeof (prdirent_t), sizeof (prdirent_t),
 163  163                  "lwp" },
 164  164          { PR_PRIV,      24 * sizeof (prdirent_t), sizeof (prdirent_t),
 165  165                  "priv" },
 166  166          { PR_PATHDIR,   25 * sizeof (prdirent_t), sizeof (prdirent_t),
 167  167                  "path" },
 168  168          { PR_CTDIR,     26 * sizeof (prdirent_t), sizeof (prdirent_t),
 169  169                  "contracts" },
 170  170  #if defined(__x86)
 171  171          { PR_LDT,       27 * sizeof (prdirent_t), sizeof (prdirent_t),
 172  172                  "ldt" },
 173  173  #endif
 174  174          { PR_ARGV,      28 * sizeof (prdirent_t), sizeof (prdirent_t),
 175  175                  "argv" },
 176  176  };
 177  177  
 178  178  #define NPIDDIRFILES    (sizeof (piddir) / sizeof (piddir[0]) - 2)
 179  179  
 180  180  /*
 181  181   * Contents of a /proc/<pid>/lwp/<lwpid> directory.
 182  182   */
 183  183  static prdirent_t lwpiddir[] = {
 184  184          { PR_LWPIDDIR,   1 * sizeof (prdirent_t), sizeof (prdirent_t),
 185  185                  "." },
 186  186          { PR_LWPDIR,     2 * sizeof (prdirent_t), sizeof (prdirent_t),
 187  187                  ".." },
 188  188          { PR_LWPCTL,     3 * sizeof (prdirent_t), sizeof (prdirent_t),
 189  189                  "lwpctl" },
 190  190          { PR_LWPSTATUS,  4 * sizeof (prdirent_t), sizeof (prdirent_t),
 191  191                  "lwpstatus" },
 192  192          { PR_LWPSINFO,   5 * sizeof (prdirent_t), sizeof (prdirent_t),
 193  193                  "lwpsinfo" },
 194  194          { PR_LWPUSAGE,   6 * sizeof (prdirent_t), sizeof (prdirent_t),
 195  195                  "lwpusage" },
 196  196          { PR_XREGS,      7 * sizeof (prdirent_t), sizeof (prdirent_t),
 197  197                  "xregs" },
 198  198          { PR_TMPLDIR,    8 * sizeof (prdirent_t), sizeof (prdirent_t),
 199  199                  "templates" },
 200  200          { PR_SPYMASTER,  9 * sizeof (prdirent_t), sizeof (prdirent_t),
 201  201                  "spymaster" },
 202  202  #if defined(__sparc)
 203  203          { PR_GWINDOWS,  10 * sizeof (prdirent_t), sizeof (prdirent_t),
 204  204                  "gwindows" },
 205  205          { PR_ASRS,      11 * sizeof (prdirent_t), sizeof (prdirent_t),
 206  206                  "asrs" },
 207  207  #endif
 208  208  };
 209  209  
 210  210  #define NLWPIDDIRFILES  (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
 211  211  
 212  212  /*
 213  213   * Span of entries in the array files (lstatus, lpsinfo, lusage).
 214  214   * We make the span larger than the size of the structure on purpose,
 215  215   * to make sure that programs cannot use the structure size by mistake.
 216  216   * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
 217  217   */
 218  218  #ifdef _LP64
 219  219  #define LSPAN(type)     (round16(sizeof (type)) + 16)
 220  220  #define LSPAN32(type)   (round8(sizeof (type)) + 8)
 221  221  #else
 222  222  #define LSPAN(type)     (round8(sizeof (type)) + 8)
 223  223  #endif
 224  224  
 225  225  static void rebuild_objdir(struct as *);
 226  226  static void prfreecommon(prcommon_t *);
 227  227  static int praccess(vnode_t *, int, int, cred_t *, caller_context_t *);
 228  228  
 229  229  static int
 230  230  propen(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct)
 231  231  {
 232  232          vnode_t *vp = *vpp;
 233  233          prnode_t *pnp = VTOP(vp);
 234  234          prcommon_t *pcp = pnp->pr_pcommon;
 235  235          prnodetype_t type = pnp->pr_type;
 236  236          vnode_t *rvp;
 237  237          vtype_t vtype;
 238  238          proc_t *p;
 239  239          int error = 0;
 240  240          prnode_t *npnp = NULL;
 241  241  
 242  242          /*
 243  243           * Nothing to do for the /proc directory itself.
 244  244           */
 245  245          if (type == PR_PROCDIR)
 246  246                  return (0);
 247  247  
 248  248          /*
 249  249           * If we are opening an underlying mapped object, reject opens
 250  250           * for writing regardless of the objects's access modes.
 251  251           * If we are opening a file in the /proc/pid/fd directory,
 252  252           * reject the open for any but a regular file or directory.
 253  253           * Just do it if we are opening the current or root directory.
 254  254           */
 255  255          switch (type) {
 256  256          case PR_OBJECT:
 257  257          case PR_FD:
 258  258          case PR_CURDIR:
 259  259          case PR_ROOTDIR:
 260  260                  rvp = pnp->pr_realvp;
 261  261                  vtype = rvp->v_type;
 262  262                  if ((type == PR_OBJECT && (flag & FWRITE)) ||
 263  263                      (type == PR_FD && vtype != VREG && vtype != VDIR))
 264  264                          error = EACCES;
 265  265                  else {
 266  266                          /*
 267  267                           * Need to hold rvp since VOP_OPEN() may release it.
 268  268                           */
 269  269                          VN_HOLD(rvp);
 270  270                          error = VOP_OPEN(&rvp, flag, cr, ct);
 271  271                          if (error) {
 272  272                                  VN_RELE(rvp);
 273  273                          } else {
 274  274                                  *vpp = rvp;
 275  275                                  VN_RELE(vp);
 276  276                          }
 277  277                  }
 278  278                  return (error);
 279  279          default:
 280  280                  break;
 281  281          }
 282  282  
 283  283          /*
 284  284           * If we are opening the pagedata file, allocate a prnode now
 285  285           * to avoid calling kmem_alloc() while holding p->p_lock.
 286  286           */
 287  287          if (type == PR_PAGEDATA || type == PR_OPAGEDATA)
 288  288                  npnp = prgetnode(vp, type);
 289  289  
 290  290          /*
 291  291           * If the process exists, lock it now.
 292  292           * Otherwise we have a race condition with prclose().
 293  293           */
 294  294          p = pr_p_lock(pnp);
 295  295          mutex_exit(&pr_pidlock);
 296  296          if (p == NULL) {
 297  297                  if (npnp != NULL)
 298  298                          prfreenode(npnp);
 299  299                  return (ENOENT);
 300  300          }
 301  301          ASSERT(p == pcp->prc_proc);
 302  302          ASSERT(p->p_proc_flag & P_PR_LOCK);
 303  303  
 304  304          /*
 305  305           * Maintain a count of opens for write.  Allow exactly one
 306  306           * O_WRITE|O_EXCL request and fail subsequent ones.
 307  307           * Don't fail opens of old (bletch!) /proc lwp files.
 308  308           * Special case for open by the process itself:
 309  309           * Always allow the open by self and discount this
 310  310           * open for other opens for writing.
 311  311           */
 312  312          if (flag & FWRITE) {
 313  313                  if (p == curproc) {
 314  314                          pcp->prc_selfopens++;
 315  315                          pnp->pr_flags |= PR_ISSELF;
 316  316                  } else if (type == PR_LWPIDFILE) {
 317  317                          /* EMPTY */;
 318  318                  } else if (flag & FEXCL) {
 319  319                          if (pcp->prc_writers > pcp->prc_selfopens) {
 320  320                                  error = EBUSY;
 321  321                                  goto out;
 322  322                          }
 323  323                          /* semantic for old /proc interface */
 324  324                          if (type == PR_PIDDIR)
 325  325                                  pcp->prc_flags |= PRC_EXCL;
 326  326                  } else if (pcp->prc_flags & PRC_EXCL) {
 327  327                          ASSERT(pcp->prc_writers > pcp->prc_selfopens);
 328  328                          error = secpolicy_proc_excl_open(cr);
 329  329                          if (error)
 330  330                                  goto out;
 331  331                  }
 332  332                  pcp->prc_writers++;
 333  333                  /*
 334  334                   * The vnode may have become invalid between the
 335  335                   * VOP_LOOKUP() of the /proc vnode and the VOP_OPEN().
 336  336                   * If so, do now what prinvalidate() should have done.
 337  337                   */
 338  338                  if ((pnp->pr_flags & PR_INVAL) ||
 339  339                      (type == PR_PIDDIR &&
 340  340                      (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) {
 341  341                          if (p != curproc)
 342  342                                  pcp->prc_selfopens++;
 343  343                          ASSERT(pcp->prc_selfopens <= pcp->prc_writers);
 344  344                          if (pcp->prc_selfopens == pcp->prc_writers)
 345  345                                  pcp->prc_flags &= ~PRC_EXCL;
 346  346                  }
 347  347          }
 348  348  
 349  349          /*
 350  350           * If this is a large file open, indicate that in our flags -- some
 351  351           * procfs structures are not off_t-neutral (e.g., priovec_t), and
 352  352           * the open will need to be differentiated where 32-bit processes
 353  353           * pass these structures across the user/kernel boundary.
 354  354           */
 355  355          if (flag & FOFFMAX)
 356  356                  pnp->pr_flags |= PR_OFFMAX;
 357  357  
 358  358          /*
 359  359           * Do file-specific things.
 360  360           */
 361  361          switch (type) {
 362  362          default:
 363  363                  break;
 364  364          case PR_PAGEDATA:
 365  365          case PR_OPAGEDATA:
 366  366                  /*
 367  367                   * Enable data collection for page data file;
 368  368                   * get unique id from the hat layer.
 369  369                   */
 370  370                  {
 371  371                          int id;
 372  372  
 373  373                          /*
 374  374                           * Drop p->p_lock to call hat_startstat()
 375  375                           */
 376  376                          mutex_exit(&p->p_lock);
 377  377                          if ((p->p_flag & SSYS) || p->p_as == &kas ||
 378  378                              (id = hat_startstat(p->p_as)) == -1) {
 379  379                                  mutex_enter(&p->p_lock);
 380  380                                  error = ENOMEM;
 381  381                          } else if (pnp->pr_hatid == 0) {
 382  382                                  mutex_enter(&p->p_lock);
 383  383                                  pnp->pr_hatid = (uint_t)id;
 384  384                          } else {
 385  385                                  mutex_enter(&p->p_lock);
 386  386                                  /*
 387  387                                   * Use our newly allocated prnode.
 388  388                                   */
 389  389                                  npnp->pr_hatid = (uint_t)id;
 390  390                                  /*
 391  391                                   * prgetnode() initialized most of the prnode.
 392  392                                   * Duplicate the remainder.
 393  393                                   */
 394  394                                  npnp->pr_ino = pnp->pr_ino;
 395  395                                  npnp->pr_common = pnp->pr_common;
 396  396                                  npnp->pr_pcommon = pnp->pr_pcommon;
 397  397                                  npnp->pr_parent = pnp->pr_parent;
 398  398                                  VN_HOLD(npnp->pr_parent);
 399  399                                  npnp->pr_index = pnp->pr_index;
 400  400  
 401  401                                  npnp->pr_next = p->p_plist;
 402  402                                  p->p_plist = PTOV(npnp);
 403  403  
 404  404                                  VN_RELE(PTOV(pnp));
 405  405                                  pnp = npnp;
 406  406                                  npnp = NULL;
 407  407                                  *vpp = PTOV(pnp);
 408  408                          }
 409  409                  }
 410  410                  break;
 411  411          }
 412  412  
 413  413  out:
 414  414          prunlock(pnp);
 415  415  
 416  416          if (npnp != NULL)
 417  417                  prfreenode(npnp);
 418  418          return (error);
 419  419  }
 420  420  
 421  421  /* ARGSUSED */
 422  422  static int
 423  423  prclose(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
 424  424          caller_context_t *ct)
 425  425  {
 426  426          prnode_t *pnp = VTOP(vp);
 427  427          prcommon_t *pcp = pnp->pr_pcommon;
 428  428          prnodetype_t type = pnp->pr_type;
 429  429          proc_t *p;
 430  430          kthread_t *t;
 431  431          user_t *up;
 432  432  
 433  433          /*
 434  434           * Nothing to do for the /proc directory itself.
 435  435           */
 436  436          if (type == PR_PROCDIR)
 437  437                  return (0);
 438  438  
 439  439          ASSERT(type != PR_OBJECT && type != PR_FD &&
 440  440              type != PR_CURDIR && type != PR_ROOTDIR);
 441  441  
 442  442          /*
 443  443           * If the process exists, lock it now.
 444  444           * Otherwise we have a race condition with propen().
 445  445           * Hold pr_pidlock across the reference to prc_selfopens,
 446  446           * and prc_writers in case there is no process anymore,
 447  447           * to cover the case of concurrent calls to prclose()
 448  448           * after the process has been reaped by freeproc().
 449  449           */
 450  450          p = pr_p_lock(pnp);
 451  451  
 452  452          /*
 453  453           * There is nothing more to do until the last close of
 454  454           * the file table entry except to clear the pr_owner
 455  455           * field of the prnode and notify any waiters
 456  456           * (their file descriptor may have just been closed).
 457  457           */
 458  458          if (count > 1) {
 459  459                  mutex_exit(&pr_pidlock);
 460  460                  if (pnp->pr_owner == curproc && !fisopen(vp))
 461  461                          pnp->pr_owner = NULL;
 462  462                  if (p != NULL) {
 463  463                          prnotify(vp);
 464  464                          prunlock(pnp);
 465  465                  }
 466  466                  return (0);
 467  467          }
 468  468  
 469  469          /*
 470  470           * Decrement the count of self-opens for writing.
 471  471           * Decrement the total count of opens for writing.
 472  472           * Cancel exclusive opens when only self-opens remain.
 473  473           */
 474  474          if (flag & FWRITE) {
 475  475                  /*
 476  476                   * prc_selfopens also contains the count of
 477  477                   * invalid writers.  See prinvalidate().
 478  478                   */
 479  479                  if ((pnp->pr_flags & (PR_ISSELF|PR_INVAL)) ||
 480  480                      (type == PR_PIDDIR &&
 481  481                      (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) {
 482  482                          ASSERT(pcp->prc_selfopens != 0);
 483  483                          --pcp->prc_selfopens;
 484  484                  }
 485  485                  ASSERT(pcp->prc_writers != 0);
 486  486                  if (--pcp->prc_writers == pcp->prc_selfopens)
 487  487                          pcp->prc_flags &= ~PRC_EXCL;
 488  488          }
 489  489          ASSERT(pcp->prc_writers >= pcp->prc_selfopens);
 490  490          mutex_exit(&pr_pidlock);
 491  491          if (pnp->pr_owner == curproc && !fisopen(vp))
 492  492                  pnp->pr_owner = NULL;
 493  493  
 494  494          /*
 495  495           * If there is no process, there is nothing more to do.
 496  496           */
 497  497          if (p == NULL)
 498  498                  return (0);
 499  499  
 500  500          ASSERT(p == pcp->prc_proc);
 501  501          prnotify(vp);   /* notify waiters */
 502  502  
 503  503          /*
 504  504           * Do file-specific things.
 505  505           */
 506  506          switch (type) {
 507  507          default:
 508  508                  break;
 509  509          case PR_PAGEDATA:
 510  510          case PR_OPAGEDATA:
 511  511                  /*
 512  512                   * This is a page data file.
 513  513                   * Free the hat level statistics.
 514  514                   * Drop p->p_lock before calling hat_freestat().
 515  515                   */
 516  516                  mutex_exit(&p->p_lock);
 517  517                  if (p->p_as != &kas && pnp->pr_hatid != 0)
 518  518                          hat_freestat(p->p_as, pnp->pr_hatid);
 519  519                  mutex_enter(&p->p_lock);
 520  520                  pnp->pr_hatid = 0;
 521  521                  break;
 522  522          }
 523  523  
 524  524          /*
 525  525           * On last close of all writable file descriptors,
 526  526           * perform run-on-last-close and/or kill-on-last-close logic.
 527  527           * Can't do this is the /proc agent lwp still exists.
 528  528           */
 529  529          if (pcp->prc_writers == 0 &&
 530  530              p->p_agenttp == NULL &&
 531  531              !(pcp->prc_flags & PRC_DESTROY) &&
 532  532              p->p_stat != SZOMB &&
 533  533              (p->p_proc_flag & (P_PR_RUNLCL|P_PR_KILLCL))) {
 534  534                  int killproc;
 535  535  
 536  536                  /*
 537  537                   * Cancel any watchpoints currently in effect.
 538  538                   * The process might disappear during this operation.
 539  539                   */
 540  540                  if (pr_cancel_watch(pnp) == NULL)
 541  541                          return (0);
 542  542                  /*
 543  543                   * If any tracing flags are set, clear them.
 544  544                   */
 545  545                  if (p->p_proc_flag & P_PR_TRACE) {
 546  546                          up = PTOU(p);
 547  547                          premptyset(&up->u_entrymask);
 548  548                          premptyset(&up->u_exitmask);
 549  549                          up->u_systrap = 0;
 550  550                  }
 551  551                  premptyset(&p->p_sigmask);
 552  552                  premptyset(&p->p_fltmask);
 553  553                  killproc = (p->p_proc_flag & P_PR_KILLCL);
 554  554                  p->p_proc_flag &= ~(P_PR_RUNLCL|P_PR_KILLCL|P_PR_TRACE);
 555  555                  /*
 556  556                   * Cancel any outstanding single-step requests.
 557  557                   */
 558  558                  if ((t = p->p_tlist) != NULL) {
 559  559                          /*
 560  560                           * Drop p_lock because prnostep() touches the stack.
 561  561                           * The loop is safe because the process is P_PR_LOCK'd.
 562  562                           */
 563  563                          mutex_exit(&p->p_lock);
 564  564                          do {
 565  565                                  prnostep(ttolwp(t));
 566  566                          } while ((t = t->t_forw) != p->p_tlist);
 567  567                          mutex_enter(&p->p_lock);
 568  568                  }
 569  569                  /*
 570  570                   * Set runnable all lwps stopped by /proc.
 571  571                   */
 572  572                  if (killproc)
 573  573                          sigtoproc(p, NULL, SIGKILL);
 574  574                  else
 575  575                          allsetrun(p);
 576  576          }
 577  577  
 578  578          prunlock(pnp);
 579  579          return (0);
 580  580  }
 581  581  
 582  582  /*
 583  583   * Array of read functions, indexed by /proc file type.
 584  584   */
 585  585  static int pr_read_inval(), pr_read_as(), pr_read_status(),
 586  586          pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
 587  587          pr_read_map(), pr_read_rmap(), pr_read_xmap(),
 588  588          pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
 589  589  #if defined(__x86)
 590  590          pr_read_ldt(),
 591  591  #endif
 592  592          pr_read_argv(),
 593  593          pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
 594  594          pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
 595  595          pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
 596  596          pr_read_spymaster(),
 597  597  #if defined(__sparc)
 598  598          pr_read_gwindows(), pr_read_asrs(),
 599  599  #endif
 600  600          pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
 601  601  
 602  602  static int (*pr_read_function[PR_NFILES])() = {
 603  603          pr_read_inval,          /* /proc                                */
 604  604          pr_read_inval,          /* /proc/self                           */
 605  605          pr_read_piddir,         /* /proc/<pid> (old /proc read())       */
 606  606          pr_read_as,             /* /proc/<pid>/as                       */
 607  607          pr_read_inval,          /* /proc/<pid>/ctl                      */
 608  608          pr_read_status,         /* /proc/<pid>/status                   */
 609  609          pr_read_lstatus,        /* /proc/<pid>/lstatus                  */
 610  610          pr_read_psinfo,         /* /proc/<pid>/psinfo                   */
 611  611          pr_read_lpsinfo,        /* /proc/<pid>/lpsinfo                  */
 612  612          pr_read_map,            /* /proc/<pid>/map                      */
 613  613          pr_read_rmap,           /* /proc/<pid>/rmap                     */
 614  614          pr_read_xmap,           /* /proc/<pid>/xmap                     */
 615  615          pr_read_cred,           /* /proc/<pid>/cred                     */
 616  616          pr_read_sigact,         /* /proc/<pid>/sigact                   */
 617  617          pr_read_auxv,           /* /proc/<pid>/auxv                     */
 618  618  #if defined(__x86)
 619  619          pr_read_ldt,            /* /proc/<pid>/ldt                      */
 620  620  #endif
 621  621          pr_read_argv,           /* /proc/<pid>/argv                     */
 622  622          pr_read_usage,          /* /proc/<pid>/usage                    */
 623  623          pr_read_lusage,         /* /proc/<pid>/lusage                   */
 624  624          pr_read_pagedata,       /* /proc/<pid>/pagedata                 */
 625  625          pr_read_watch,          /* /proc/<pid>/watch                    */
 626  626          pr_read_inval,          /* /proc/<pid>/cwd                      */
 627  627          pr_read_inval,          /* /proc/<pid>/root                     */
 628  628          pr_read_inval,          /* /proc/<pid>/fd                       */
 629  629          pr_read_inval,          /* /proc/<pid>/fd/nn                    */
 630  630          pr_read_inval,          /* /proc/<pid>/object                   */
 631  631          pr_read_inval,          /* /proc/<pid>/object/xxx               */
 632  632          pr_read_inval,          /* /proc/<pid>/lwp                      */
 633  633          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>              */
 634  634          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl       */
 635  635          pr_read_lwpstatus,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus    */
 636  636          pr_read_lwpsinfo,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo     */
 637  637          pr_read_lwpusage,       /* /proc/<pid>/lwp/<lwpid>/lwpusage     */
 638  638          pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs        */
 639  639          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates    */
 640  640          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
 641  641          pr_read_spymaster,      /* /proc/<pid>/lwp/<lwpid>/spymaster    */
 642  642  #if defined(__sparc)
 643  643          pr_read_gwindows,       /* /proc/<pid>/lwp/<lwpid>/gwindows     */
 644  644          pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs         */
 645  645  #endif
 646  646          pr_read_priv,           /* /proc/<pid>/priv                     */
 647  647          pr_read_inval,          /* /proc/<pid>/path                     */
 648  648          pr_read_inval,          /* /proc/<pid>/path/xxx                 */
 649  649          pr_read_inval,          /* /proc/<pid>/contracts                */
 650  650          pr_read_inval,          /* /proc/<pid>/contracts/<ctid>         */
 651  651          pr_read_pidfile,        /* old process file                     */
 652  652          pr_read_pidfile,        /* old lwp file                         */
 653  653          pr_read_opagedata,      /* old pagedata file                    */
 654  654  };
 655  655  
 656  656  /* ARGSUSED */
 657  657  static int
 658  658  pr_read_inval(prnode_t *pnp, uio_t *uiop)
 659  659  {
 660  660          /*
 661  661           * No read() on any /proc directory, use getdents(2) instead.
 662  662           * Cannot read a control file either.
 663  663           * An underlying mapped object file cannot get here.
 664  664           */
 665  665          return (EINVAL);
 666  666  }
 667  667  
 668  668  static int
 669  669  pr_uioread(void *base, long count, uio_t *uiop)
 670  670  {
 671  671          int error = 0;
 672  672  
 673  673          ASSERT(count >= 0);
 674  674          count -= uiop->uio_offset;
 675  675          if (count > 0 && uiop->uio_offset >= 0) {
 676  676                  error = uiomove((char *)base + uiop->uio_offset,
 677  677                      count, UIO_READ, uiop);
 678  678          }
 679  679  
 680  680          return (error);
 681  681  }
 682  682  
 683  683  static int
 684  684  pr_read_argv(prnode_t *pnp, uio_t *uiop)
 685  685  {
 686  686          char *args;
 687  687          int error;
 688  688          size_t asz = prmaxargvlen, sz;
 689  689  
 690  690          /*
 691  691           * Allocate a scratch buffer for collection of the process arguments.
 692  692           */
 693  693          args = kmem_alloc(asz, KM_SLEEP);
 694  694  
 695  695          ASSERT(pnp->pr_type == PR_ARGV);
 696  696  
 697  697          if ((error = prlock(pnp, ZNO)) != 0) {
 698  698                  kmem_free(args, asz);
 699  699                  return (error);
 700  700          }
 701  701  
 702  702          if ((error = prreadargv(pnp->pr_common->prc_proc, args, asz,
 703  703              &sz)) != 0) {
 704  704                  prunlock(pnp);
 705  705                  kmem_free(args, asz);
 706  706                  return (error);
 707  707          }
 708  708  
 709  709          prunlock(pnp);
 710  710  
 711  711          error = pr_uioread(args, sz, uiop);
 712  712  
 713  713          kmem_free(args, asz);
 714  714  
 715  715          return (error);
 716  716  }
 717  717  
 718  718  static int
 719  719  pr_read_as(prnode_t *pnp, uio_t *uiop)
 720  720  {
 721  721          int error;
 722  722  
 723  723          ASSERT(pnp->pr_type == PR_AS);
 724  724  
 725  725          if ((error = prlock(pnp, ZNO)) == 0) {
 726  726                  proc_t *p = pnp->pr_common->prc_proc;
 727  727                  struct as *as = p->p_as;
 728  728  
 729  729                  /*
 730  730                   * /proc I/O cannot be done to a system process.
 731  731                   * A 32-bit process cannot read a 64-bit process.
 732  732                   */
 733  733                  if ((p->p_flag & SSYS) || as == &kas) {
 734  734                          error = 0;
 735  735  #ifdef _SYSCALL32_IMPL
 736  736                  } else if (curproc->p_model == DATAMODEL_ILP32 &&
 737  737                      PROCESS_NOT_32BIT(p)) {
 738  738                          error = EOVERFLOW;
 739  739  #endif
 740  740                  } else {
 741  741                          /*
 742  742                           * We don't hold p_lock over an i/o operation because
 743  743                           * that could lead to deadlock with the clock thread.
 744  744                           */
 745  745                          mutex_exit(&p->p_lock);
 746  746                          error = prusrio(p, UIO_READ, uiop, 0);
 747  747                          mutex_enter(&p->p_lock);
 748  748                  }
 749  749                  prunlock(pnp);
 750  750          }
 751  751  
 752  752          return (error);
 753  753  }
 754  754  
 755  755  static int
 756  756  pr_read_status(prnode_t *pnp, uio_t *uiop)
 757  757  {
 758  758          pstatus_t *sp;
 759  759          int error;
 760  760  
 761  761          ASSERT(pnp->pr_type == PR_STATUS);
 762  762  
 763  763          /*
 764  764           * We kmem_alloc() the pstatus structure because
 765  765           * it is so big it might blow the kernel stack.
 766  766           */
 767  767          sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
 768  768          if ((error = prlock(pnp, ZNO)) == 0) {
 769  769                  prgetstatus(pnp->pr_common->prc_proc, sp, VTOZONE(PTOV(pnp)));
 770  770                  prunlock(pnp);
 771  771                  error = pr_uioread(sp, sizeof (*sp), uiop);
 772  772          }
 773  773          kmem_free(sp, sizeof (*sp));
 774  774          return (error);
 775  775  }
 776  776  
 777  777  static int
 778  778  pr_read_lstatus(prnode_t *pnp, uio_t *uiop)
 779  779  {
 780  780          proc_t *p;
 781  781          kthread_t *t;
 782  782          lwpdir_t *ldp;
 783  783          size_t size;
 784  784          prheader_t *php;
 785  785          lwpstatus_t *sp;
 786  786          int error;
 787  787          int nlwp;
 788  788          int i;
 789  789  
 790  790          ASSERT(pnp->pr_type == PR_LSTATUS);
 791  791  
 792  792          if ((error = prlock(pnp, ZNO)) != 0)
 793  793                  return (error);
 794  794          p = pnp->pr_common->prc_proc;
 795  795          nlwp = p->p_lwpcnt;
 796  796          size = sizeof (prheader_t) + nlwp * LSPAN(lwpstatus_t);
 797  797  
 798  798          /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
 799  799          mutex_exit(&p->p_lock);
 800  800          php = kmem_zalloc(size, KM_SLEEP);
 801  801          mutex_enter(&p->p_lock);
 802  802          /* p->p_lwpcnt can't change while process is locked */
 803  803          ASSERT(nlwp == p->p_lwpcnt);
 804  804  
 805  805          php->pr_nent = nlwp;
 806  806          php->pr_entsize = LSPAN(lwpstatus_t);
 807  807  
 808  808          sp = (lwpstatus_t *)(php + 1);
 809  809          for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
 810  810                  if (ldp->ld_entry == NULL ||
 811  811                      (t = ldp->ld_entry->le_thread) == NULL)
 812  812                          continue;
 813  813                  prgetlwpstatus(t, sp, VTOZONE(PTOV(pnp)));
 814  814                  sp = (lwpstatus_t *)((caddr_t)sp + LSPAN(lwpstatus_t));
 815  815          }
 816  816          prunlock(pnp);
 817  817  
 818  818          error = pr_uioread(php, size, uiop);
 819  819          kmem_free(php, size);
 820  820          return (error);
 821  821  }
 822  822  
 823  823  static int
 824  824  pr_read_psinfo(prnode_t *pnp, uio_t *uiop)
 825  825  {
 826  826          psinfo_t psinfo;
 827  827          proc_t *p;
 828  828          int error = 0;
 829  829  
 830  830          ASSERT(pnp->pr_type == PR_PSINFO);
 831  831  
 832  832          /*
 833  833           * We don't want the full treatment of prlock(pnp) here.
 834  834           * This file is world-readable and never goes invalid.
 835  835           * It doesn't matter if we are in the middle of an exec().
 836  836           */
 837  837          p = pr_p_lock(pnp);
 838  838          mutex_exit(&pr_pidlock);
 839  839          if (p == NULL)
 840  840                  error = ENOENT;
 841  841          else {
 842  842                  ASSERT(p == pnp->pr_common->prc_proc);
 843  843                  prgetpsinfo(p, &psinfo);
 844  844                  prunlock(pnp);
 845  845                  error = pr_uioread(&psinfo, sizeof (psinfo), uiop);
 846  846          }
 847  847          return (error);
 848  848  }
 849  849  
 850  850  static int
 851  851  pr_read_lpsinfo(prnode_t *pnp, uio_t *uiop)
 852  852  {
 853  853          proc_t *p;
 854  854          kthread_t *t;
 855  855          lwpdir_t *ldp;
 856  856          lwpent_t *lep;
 857  857          size_t size;
 858  858          prheader_t *php;
 859  859          lwpsinfo_t *sp;
 860  860          int error;
 861  861          int nlwp;
 862  862          int i;
 863  863  
 864  864          ASSERT(pnp->pr_type == PR_LPSINFO);
 865  865  
 866  866          /*
 867  867           * We don't want the full treatment of prlock(pnp) here.
 868  868           * This file is world-readable and never goes invalid.
 869  869           * It doesn't matter if we are in the middle of an exec().
 870  870           */
 871  871          p = pr_p_lock(pnp);
 872  872          mutex_exit(&pr_pidlock);
 873  873          if (p == NULL)
 874  874                  return (ENOENT);
 875  875          ASSERT(p == pnp->pr_common->prc_proc);
 876  876          if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) {
 877  877                  prunlock(pnp);
 878  878                  return (ENOENT);
 879  879          }
 880  880          size = sizeof (prheader_t) + nlwp * LSPAN(lwpsinfo_t);
 881  881  
 882  882          /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
 883  883          mutex_exit(&p->p_lock);
 884  884          php = kmem_zalloc(size, KM_SLEEP);
 885  885          mutex_enter(&p->p_lock);
 886  886          /* p->p_lwpcnt can't change while process is locked */
 887  887          ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt);
 888  888  
 889  889          php->pr_nent = nlwp;
 890  890          php->pr_entsize = LSPAN(lwpsinfo_t);
 891  891  
 892  892          sp = (lwpsinfo_t *)(php + 1);
 893  893          for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
 894  894                  if ((lep = ldp->ld_entry) == NULL)
 895  895                          continue;
 896  896                  if ((t = lep->le_thread) != NULL)
 897  897                          prgetlwpsinfo(t, sp);
 898  898                  else {
 899  899                          bzero(sp, sizeof (*sp));
 900  900                          sp->pr_lwpid = lep->le_lwpid;
 901  901                          sp->pr_state = SZOMB;
 902  902                          sp->pr_sname = 'Z';
 903  903                          sp->pr_start.tv_sec = lep->le_start;
 904  904                          sp->pr_bindpro = PBIND_NONE;
 905  905                          sp->pr_bindpset = PS_NONE;
 906  906                  }
 907  907                  sp = (lwpsinfo_t *)((caddr_t)sp + LSPAN(lwpsinfo_t));
 908  908          }
 909  909          prunlock(pnp);
 910  910  
 911  911          error = pr_uioread(php, size, uiop);
 912  912          kmem_free(php, size);
 913  913          return (error);
 914  914  }
 915  915  
 916  916  static int
 917  917  pr_read_map_common(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
 918  918  {
 919  919          proc_t *p;
 920  920          struct as *as;
 921  921          list_t iolhead;
 922  922          int error;
 923  923  
 924  924  readmap_common:
 925  925          if ((error = prlock(pnp, ZNO)) != 0)
 926  926                  return (error);
 927  927  
 928  928          p = pnp->pr_common->prc_proc;
 929  929          as = p->p_as;
 930  930  
 931  931          if ((p->p_flag & SSYS) || as == &kas) {
 932  932                  prunlock(pnp);
 933  933                  return (0);
 934  934          }
 935  935  
 936  936          if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
 937  937                  prunlock(pnp);
 938  938                  delay(1);
 939  939                  goto readmap_common;
 940  940          }
 941  941          mutex_exit(&p->p_lock);
 942  942  
 943  943          switch (type) {
 944  944          case PR_XMAP:
 945  945                  error = prgetxmap(p, &iolhead);
 946  946                  break;
 947  947          case PR_RMAP:
 948  948                  error = prgetmap(p, 1, &iolhead);
 949  949                  break;
 950  950          case PR_MAP:
 951  951                  error = prgetmap(p, 0, &iolhead);
 952  952                  break;
 953  953          }
 954  954  
 955  955          AS_LOCK_EXIT(as);
 956  956          mutex_enter(&p->p_lock);
 957  957          prunlock(pnp);
 958  958  
 959  959          error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
 960  960  
 961  961          return (error);
 962  962  }
 963  963  
 964  964  static int
 965  965  pr_read_map(prnode_t *pnp, uio_t *uiop)
 966  966  {
 967  967          ASSERT(pnp->pr_type == PR_MAP);
 968  968          return (pr_read_map_common(pnp, uiop, pnp->pr_type));
 969  969  }
 970  970  
 971  971  static int
 972  972  pr_read_rmap(prnode_t *pnp, uio_t *uiop)
 973  973  {
 974  974          ASSERT(pnp->pr_type == PR_RMAP);
 975  975          return (pr_read_map_common(pnp, uiop, pnp->pr_type));
 976  976  }
 977  977  
 978  978  static int
 979  979  pr_read_xmap(prnode_t *pnp, uio_t *uiop)
 980  980  {
 981  981          ASSERT(pnp->pr_type == PR_XMAP);
 982  982          return (pr_read_map_common(pnp, uiop, pnp->pr_type));
 983  983  }
 984  984  
 985  985  static int
 986  986  pr_read_cred(prnode_t *pnp, uio_t *uiop)
 987  987  {
 988  988          proc_t *p;
 989  989          prcred_t *pcrp;
 990  990          int error;
 991  991          size_t count;
 992  992  
 993  993          ASSERT(pnp->pr_type == PR_CRED);
 994  994  
 995  995          /*
 996  996           * We kmem_alloc() the prcred_t structure because
 997  997           * the number of supplementary groups is variable.
 998  998           */
 999  999          pcrp =
1000 1000              kmem_alloc(sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1),
1001 1001              KM_SLEEP);
1002 1002  
1003 1003          if ((error = prlock(pnp, ZNO)) != 0)
1004 1004                  goto out;
1005 1005          p = pnp->pr_common->prc_proc;
1006 1006          ASSERT(p != NULL);
1007 1007  
1008 1008          prgetcred(p, pcrp);
1009 1009          prunlock(pnp);
1010 1010  
1011 1011          count = sizeof (prcred_t);
1012 1012          if (pcrp->pr_ngroups > 1)
1013 1013                  count += sizeof (gid_t) * (pcrp->pr_ngroups - 1);
1014 1014          error = pr_uioread(pcrp, count, uiop);
1015 1015  out:
1016 1016          kmem_free(pcrp, sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1));
1017 1017          return (error);
1018 1018  }
1019 1019  
1020 1020  static int
1021 1021  pr_read_priv(prnode_t *pnp, uio_t *uiop)
1022 1022  {
1023 1023          proc_t *p;
1024 1024          size_t psize = prgetprivsize();
1025 1025          prpriv_t *ppriv = kmem_alloc(psize, KM_SLEEP);
1026 1026          int error;
1027 1027  
1028 1028          ASSERT(pnp->pr_type == PR_PRIV);
1029 1029  
1030 1030          if ((error = prlock(pnp, ZNO)) != 0)
1031 1031                  goto out;
1032 1032          p = pnp->pr_common->prc_proc;
1033 1033          ASSERT(p != NULL);
1034 1034  
1035 1035          prgetpriv(p, ppriv);
1036 1036          prunlock(pnp);
1037 1037  
1038 1038          error = pr_uioread(ppriv, psize, uiop);
1039 1039  out:
1040 1040          kmem_free(ppriv, psize);
1041 1041          return (error);
1042 1042  }
1043 1043  
1044 1044  static int
1045 1045  pr_read_sigact(prnode_t *pnp, uio_t *uiop)
1046 1046  {
1047 1047          int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1048 1048          proc_t *p;
1049 1049          struct sigaction *sap;
1050 1050          int sig;
1051 1051          int error;
1052 1052          user_t *up;
1053 1053  
1054 1054          ASSERT(pnp->pr_type == PR_SIGACT);
1055 1055  
1056 1056          /*
1057 1057           * We kmem_alloc() the sigaction array because
1058 1058           * it is so big it might blow the kernel stack.
1059 1059           */
1060 1060          sap = kmem_alloc((nsig-1) * sizeof (struct sigaction), KM_SLEEP);
1061 1061  
1062 1062          if ((error = prlock(pnp, ZNO)) != 0)
1063 1063                  goto out;
1064 1064          p = pnp->pr_common->prc_proc;
1065 1065          ASSERT(p != NULL);
1066 1066  
1067 1067          if (uiop->uio_offset >= (nsig-1)*sizeof (struct sigaction)) {
1068 1068                  prunlock(pnp);
1069 1069                  goto out;
1070 1070          }
1071 1071  
1072 1072          up = PTOU(p);
1073 1073          for (sig = 1; sig < nsig; sig++)
1074 1074                  prgetaction(p, up, sig, &sap[sig-1]);
1075 1075          prunlock(pnp);
1076 1076  
1077 1077          error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction), uiop);
1078 1078  out:
1079 1079          kmem_free(sap, (nsig-1) * sizeof (struct sigaction));
1080 1080          return (error);
1081 1081  }
1082 1082  
1083 1083  static int
1084 1084  pr_read_auxv(prnode_t *pnp, uio_t *uiop)
1085 1085  {
1086 1086          auxv_t auxv[__KERN_NAUXV_IMPL];
1087 1087          proc_t *p;
1088 1088          user_t *up;
1089 1089          int error;
1090 1090  
1091 1091          ASSERT(pnp->pr_type == PR_AUXV);
1092 1092  
1093 1093          if ((error = prlock(pnp, ZNO)) != 0)
1094 1094                  return (error);
1095 1095  
1096 1096          if (uiop->uio_offset >= sizeof (auxv)) {
1097 1097                  prunlock(pnp);
1098 1098                  return (0);
1099 1099          }
1100 1100  
1101 1101          p = pnp->pr_common->prc_proc;
1102 1102          up = PTOU(p);
1103 1103          bcopy(up->u_auxv, auxv, sizeof (auxv));
1104 1104          prunlock(pnp);
1105 1105  
1106 1106          return (pr_uioread(auxv, sizeof (auxv), uiop));
1107 1107  }
1108 1108  
1109 1109  #if defined(__x86)
1110 1110  /*
1111 1111   * XX64
1112 1112   *      This is almost certainly broken for the amd64 kernel, because
1113 1113   *      we have two kinds of LDT structures to export -- one for compatibility
1114 1114   *      mode, and one for long mode, sigh.
1115 1115   *
1116 1116   *      For now lets just have a ldt of size 0 for 64-bit processes.
1117 1117   */
1118 1118  static int
1119 1119  pr_read_ldt(prnode_t *pnp, uio_t *uiop)
1120 1120  {
1121 1121          proc_t *p;
1122 1122          struct ssd *ssd;
1123 1123          size_t size;
1124 1124          int error;
1125 1125  
1126 1126          ASSERT(pnp->pr_type == PR_LDT);
1127 1127  
1128 1128          if ((error = prlock(pnp, ZNO)) != 0)
1129 1129                  return (error);
1130 1130          p = pnp->pr_common->prc_proc;
1131 1131  
1132 1132          mutex_exit(&p->p_lock);
1133 1133          mutex_enter(&p->p_ldtlock);
1134 1134          size = prnldt(p) * sizeof (struct ssd);
1135 1135          if (uiop->uio_offset >= size) {
1136 1136                  mutex_exit(&p->p_ldtlock);
1137 1137                  mutex_enter(&p->p_lock);
1138 1138                  prunlock(pnp);
1139 1139                  return (0);
1140 1140          }
1141 1141  
1142 1142          ssd = kmem_alloc(size, KM_SLEEP);
1143 1143          prgetldt(p, ssd);
1144 1144          mutex_exit(&p->p_ldtlock);
1145 1145          mutex_enter(&p->p_lock);
1146 1146          prunlock(pnp);
1147 1147  
1148 1148          error = pr_uioread(ssd, size, uiop);
1149 1149          kmem_free(ssd, size);
1150 1150          return (error);
1151 1151  }
1152 1152  #endif  /* __x86 */
1153 1153  
1154 1154  static int
1155 1155  pr_read_usage(prnode_t *pnp, uio_t *uiop)
1156 1156  {
1157 1157          prhusage_t *pup;
1158 1158          prusage_t *upup;
1159 1159          proc_t *p;
1160 1160          kthread_t *t;
1161 1161          int error;
1162 1162  
1163 1163          ASSERT(pnp->pr_type == PR_USAGE);
1164 1164  
1165 1165          /* allocate now, before locking the process */
1166 1166          pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
1167 1167          upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
1168 1168  
1169 1169          /*
1170 1170           * We don't want the full treatment of prlock(pnp) here.
1171 1171           * This file is world-readable and never goes invalid.
1172 1172           * It doesn't matter if we are in the middle of an exec().
1173 1173           */
1174 1174          p = pr_p_lock(pnp);
1175 1175          mutex_exit(&pr_pidlock);
1176 1176          if (p == NULL) {
1177 1177                  error = ENOENT;
1178 1178                  goto out;
1179 1179          }
1180 1180          ASSERT(p == pnp->pr_common->prc_proc);
1181 1181  
1182 1182          if (uiop->uio_offset >= sizeof (prusage_t)) {
1183 1183                  prunlock(pnp);
1184 1184                  error = 0;
1185 1185                  goto out;
1186 1186          }
1187 1187  
1188 1188          pup->pr_tstamp = gethrtime();
1189 1189  
1190 1190          pup->pr_count  = p->p_defunct;
1191 1191          pup->pr_create = p->p_mstart;
1192 1192          pup->pr_term   = p->p_mterm;
1193 1193  
1194 1194          pup->pr_rtime    = p->p_mlreal;
1195 1195          pup->pr_utime    = p->p_acct[LMS_USER];
1196 1196          pup->pr_stime    = p->p_acct[LMS_SYSTEM];
1197 1197          pup->pr_ttime    = p->p_acct[LMS_TRAP];
1198 1198          pup->pr_tftime   = p->p_acct[LMS_TFAULT];
1199 1199          pup->pr_dftime   = p->p_acct[LMS_DFAULT];
1200 1200          pup->pr_kftime   = p->p_acct[LMS_KFAULT];
1201 1201          pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
1202 1202          pup->pr_slptime  = p->p_acct[LMS_SLEEP];
1203 1203          pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
1204 1204          pup->pr_stoptime = p->p_acct[LMS_STOPPED];
1205 1205  
1206 1206          pup->pr_minf  = p->p_ru.minflt;
1207 1207          pup->pr_majf  = p->p_ru.majflt;
1208 1208          pup->pr_nswap = p->p_ru.nswap;
1209 1209          pup->pr_inblk = p->p_ru.inblock;
1210 1210          pup->pr_oublk = p->p_ru.oublock;
1211 1211          pup->pr_msnd  = p->p_ru.msgsnd;
1212 1212          pup->pr_mrcv  = p->p_ru.msgrcv;
1213 1213          pup->pr_sigs  = p->p_ru.nsignals;
1214 1214          pup->pr_vctx  = p->p_ru.nvcsw;
1215 1215          pup->pr_ictx  = p->p_ru.nivcsw;
1216 1216          pup->pr_sysc  = p->p_ru.sysc;
1217 1217          pup->pr_ioch  = p->p_ru.ioch;
1218 1218  
1219 1219          /*
1220 1220           * Add the usage information for each active lwp.
1221 1221           */
1222 1222          if ((t = p->p_tlist) != NULL &&
1223 1223              !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) {
1224 1224                  do {
1225 1225                          if (t->t_proc_flag & TP_LWPEXIT)
1226 1226                                  continue;
1227 1227                          pup->pr_count++;
1228 1228                          praddusage(t, pup);
1229 1229                  } while ((t = t->t_forw) != p->p_tlist);
1230 1230          }
1231 1231  
1232 1232          prunlock(pnp);
1233 1233  
1234 1234          prcvtusage(pup, upup);
1235 1235  
1236 1236          error = pr_uioread(upup, sizeof (prusage_t), uiop);
1237 1237  out:
1238 1238          kmem_free(pup, sizeof (*pup));
1239 1239          kmem_free(upup, sizeof (*upup));
1240 1240          return (error);
1241 1241  }
1242 1242  
1243 1243  static int
1244 1244  pr_read_lusage(prnode_t *pnp, uio_t *uiop)
1245 1245  {
1246 1246          int nlwp;
1247 1247          prhusage_t *pup;
1248 1248          prheader_t *php;
1249 1249          prusage_t *upup;
1250 1250          size_t size;
1251 1251          hrtime_t curtime;
1252 1252          proc_t *p;
1253 1253          kthread_t *t;
1254 1254          lwpdir_t *ldp;
1255 1255          int error;
1256 1256          int i;
1257 1257  
1258 1258          ASSERT(pnp->pr_type == PR_LUSAGE);
1259 1259  
1260 1260          /*
1261 1261           * We don't want the full treatment of prlock(pnp) here.
1262 1262           * This file is world-readable and never goes invalid.
1263 1263           * It doesn't matter if we are in the middle of an exec().
1264 1264           */
1265 1265          p = pr_p_lock(pnp);
1266 1266          mutex_exit(&pr_pidlock);
1267 1267          if (p == NULL)
1268 1268                  return (ENOENT);
1269 1269          ASSERT(p == pnp->pr_common->prc_proc);
1270 1270          if ((nlwp = p->p_lwpcnt) == 0) {
1271 1271                  prunlock(pnp);
1272 1272                  return (ENOENT);
1273 1273          }
1274 1274  
1275 1275          size = sizeof (prheader_t) + (nlwp + 1) * LSPAN(prusage_t);
1276 1276          if (uiop->uio_offset >= size) {
1277 1277                  prunlock(pnp);
1278 1278                  return (0);
1279 1279          }
1280 1280  
1281 1281          /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1282 1282          mutex_exit(&p->p_lock);
1283 1283          pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP);
1284 1284          mutex_enter(&p->p_lock);
1285 1285          /* p->p_lwpcnt can't change while process is locked */
1286 1286          ASSERT(nlwp == p->p_lwpcnt);
1287 1287  
1288 1288          php = (prheader_t *)(pup + 1);
1289 1289          upup = (prusage_t *)(php + 1);
1290 1290  
1291 1291          php->pr_nent = nlwp + 1;
1292 1292          php->pr_entsize = LSPAN(prusage_t);
1293 1293  
1294 1294          curtime = gethrtime();
1295 1295  
1296 1296          /*
1297 1297           * First the summation over defunct lwps.
1298 1298           */
1299 1299          pup->pr_count  = p->p_defunct;
1300 1300          pup->pr_tstamp = curtime;
1301 1301          pup->pr_create = p->p_mstart;
1302 1302          pup->pr_term   = p->p_mterm;
1303 1303  
1304 1304          pup->pr_rtime    = p->p_mlreal;
1305 1305          pup->pr_utime    = p->p_acct[LMS_USER];
1306 1306          pup->pr_stime    = p->p_acct[LMS_SYSTEM];
1307 1307          pup->pr_ttime    = p->p_acct[LMS_TRAP];
1308 1308          pup->pr_tftime   = p->p_acct[LMS_TFAULT];
1309 1309          pup->pr_dftime   = p->p_acct[LMS_DFAULT];
1310 1310          pup->pr_kftime   = p->p_acct[LMS_KFAULT];
1311 1311          pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
1312 1312          pup->pr_slptime  = p->p_acct[LMS_SLEEP];
1313 1313          pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
1314 1314          pup->pr_stoptime = p->p_acct[LMS_STOPPED];
1315 1315  
1316 1316          pup->pr_minf  = p->p_ru.minflt;
1317 1317          pup->pr_majf  = p->p_ru.majflt;
1318 1318          pup->pr_nswap = p->p_ru.nswap;
1319 1319          pup->pr_inblk = p->p_ru.inblock;
1320 1320          pup->pr_oublk = p->p_ru.oublock;
1321 1321          pup->pr_msnd  = p->p_ru.msgsnd;
1322 1322          pup->pr_mrcv  = p->p_ru.msgrcv;
1323 1323          pup->pr_sigs  = p->p_ru.nsignals;
1324 1324          pup->pr_vctx  = p->p_ru.nvcsw;
1325 1325          pup->pr_ictx  = p->p_ru.nivcsw;
1326 1326          pup->pr_sysc  = p->p_ru.sysc;
1327 1327          pup->pr_ioch  = p->p_ru.ioch;
1328 1328  
1329 1329          prcvtusage(pup, upup);
1330 1330  
1331 1331          /*
1332 1332           * Fill one prusage struct for each active lwp.
1333 1333           */
1334 1334          for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1335 1335                  if (ldp->ld_entry == NULL ||
1336 1336                      (t = ldp->ld_entry->le_thread) == NULL)
1337 1337                          continue;
1338 1338                  ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
1339 1339                  ASSERT(nlwp > 0);
1340 1340                  --nlwp;
1341 1341                  upup = (prusage_t *)((caddr_t)upup + LSPAN(prusage_t));
1342 1342                  prgetusage(t, pup);
1343 1343                  prcvtusage(pup, upup);
1344 1344          }
1345 1345          ASSERT(nlwp == 0);
1346 1346  
1347 1347          prunlock(pnp);
1348 1348  
1349 1349          error = pr_uioread(php, size, uiop);
1350 1350          kmem_free(pup, size + sizeof (prhusage_t));
1351 1351          return (error);
1352 1352  }
1353 1353  
1354 1354  static int
1355 1355  pr_read_pagedata(prnode_t *pnp, uio_t *uiop)
1356 1356  {
1357 1357          proc_t *p;
1358 1358          int error;
1359 1359  
1360 1360          ASSERT(pnp->pr_type == PR_PAGEDATA);
1361 1361  
1362 1362          if ((error = prlock(pnp, ZNO)) != 0)
1363 1363                  return (error);
1364 1364  
1365 1365          p = pnp->pr_common->prc_proc;
1366 1366          if ((p->p_flag & SSYS) || p->p_as == &kas) {
1367 1367                  prunlock(pnp);
1368 1368                  return (0);
1369 1369          }
1370 1370  
1371 1371          mutex_exit(&p->p_lock);
1372 1372          error = prpdread(p, pnp->pr_hatid, uiop);
1373 1373          mutex_enter(&p->p_lock);
1374 1374  
1375 1375          prunlock(pnp);
1376 1376          return (error);
1377 1377  }
1378 1378  
1379 1379  static int
1380 1380  pr_read_opagedata(prnode_t *pnp, uio_t *uiop)
1381 1381  {
1382 1382          proc_t *p;
1383 1383          struct as *as;
1384 1384          int error;
1385 1385  
1386 1386          ASSERT(pnp->pr_type == PR_OPAGEDATA);
1387 1387  
1388 1388          if ((error = prlock(pnp, ZNO)) != 0)
1389 1389                  return (error);
1390 1390  
1391 1391          p = pnp->pr_common->prc_proc;
1392 1392          as = p->p_as;
1393 1393          if ((p->p_flag & SSYS) || as == &kas) {
1394 1394                  prunlock(pnp);
1395 1395                  return (0);
1396 1396          }
1397 1397  
1398 1398          mutex_exit(&p->p_lock);
1399 1399          error = oprpdread(as, pnp->pr_hatid, uiop);
1400 1400          mutex_enter(&p->p_lock);
1401 1401  
1402 1402          prunlock(pnp);
1403 1403          return (error);
1404 1404  }
1405 1405  
1406 1406  static int
1407 1407  pr_read_watch(prnode_t *pnp, uio_t *uiop)
1408 1408  {
1409 1409          proc_t *p;
1410 1410          int error;
1411 1411          prwatch_t *Bpwp;
1412 1412          size_t size;
1413 1413          prwatch_t *pwp;
1414 1414          int nwarea;
1415 1415          struct watched_area *pwarea;
1416 1416  
1417 1417          ASSERT(pnp->pr_type == PR_WATCH);
1418 1418  
1419 1419          if ((error = prlock(pnp, ZNO)) != 0)
1420 1420                  return (error);
1421 1421  
1422 1422          p = pnp->pr_common->prc_proc;
1423 1423          nwarea = avl_numnodes(&p->p_warea);
1424 1424          size = nwarea * sizeof (prwatch_t);
1425 1425          if (uiop->uio_offset >= size) {
1426 1426                  prunlock(pnp);
1427 1427                  return (0);
1428 1428          }
1429 1429  
1430 1430          /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1431 1431          mutex_exit(&p->p_lock);
1432 1432          Bpwp = pwp = kmem_zalloc(size, KM_SLEEP);
1433 1433          mutex_enter(&p->p_lock);
1434 1434          /* p->p_nwarea can't change while process is locked */
1435 1435          ASSERT(nwarea == avl_numnodes(&p->p_warea));
1436 1436  
1437 1437          /* gather the watched areas */
1438 1438          for (pwarea = avl_first(&p->p_warea); pwarea != NULL;
1439 1439              pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) {
1440 1440                  pwp->pr_vaddr = (uintptr_t)pwarea->wa_vaddr;
1441 1441                  pwp->pr_size = pwarea->wa_eaddr - pwarea->wa_vaddr;
1442 1442                  pwp->pr_wflags = (int)pwarea->wa_flags;
1443 1443          }
1444 1444  
1445 1445          prunlock(pnp);
1446 1446  
1447 1447          error = pr_uioread(Bpwp, size, uiop);
1448 1448          kmem_free(Bpwp, size);
1449 1449          return (error);
1450 1450  }
1451 1451  
1452 1452  static int
1453 1453  pr_read_lwpstatus(prnode_t *pnp, uio_t *uiop)
1454 1454  {
1455 1455          lwpstatus_t *sp;
1456 1456          int error;
1457 1457  
1458 1458          ASSERT(pnp->pr_type == PR_LWPSTATUS);
1459 1459  
1460 1460          /*
1461 1461           * We kmem_alloc() the lwpstatus structure because
1462 1462           * it is so big it might blow the kernel stack.
1463 1463           */
1464 1464          sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
1465 1465  
1466 1466          if ((error = prlock(pnp, ZNO)) != 0)
1467 1467                  goto out;
1468 1468  
1469 1469          if (uiop->uio_offset >= sizeof (*sp)) {
1470 1470                  prunlock(pnp);
1471 1471                  goto out;
1472 1472          }
1473 1473  
1474 1474          prgetlwpstatus(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp)));
1475 1475          prunlock(pnp);
1476 1476  
1477 1477          error = pr_uioread(sp, sizeof (*sp), uiop);
1478 1478  out:
1479 1479          kmem_free(sp, sizeof (*sp));
1480 1480          return (error);
1481 1481  }
1482 1482  
1483 1483  static int
1484 1484  pr_read_lwpsinfo(prnode_t *pnp, uio_t *uiop)
1485 1485  {
1486 1486          lwpsinfo_t lwpsinfo;
1487 1487          proc_t *p;
1488 1488          kthread_t *t;
1489 1489          lwpent_t *lep;
1490 1490  
1491 1491          ASSERT(pnp->pr_type == PR_LWPSINFO);
1492 1492  
1493 1493          /*
1494 1494           * We don't want the full treatment of prlock(pnp) here.
1495 1495           * This file is world-readable and never goes invalid.
1496 1496           * It doesn't matter if we are in the middle of an exec().
1497 1497           */
1498 1498          p = pr_p_lock(pnp);
1499 1499          mutex_exit(&pr_pidlock);
1500 1500          if (p == NULL)
1501 1501                  return (ENOENT);
1502 1502          ASSERT(p == pnp->pr_common->prc_proc);
1503 1503          if (pnp->pr_common->prc_tslot == -1) {
1504 1504                  prunlock(pnp);
1505 1505                  return (ENOENT);
1506 1506          }
1507 1507  
1508 1508          if (uiop->uio_offset >= sizeof (lwpsinfo)) {
1509 1509                  prunlock(pnp);
1510 1510                  return (0);
1511 1511          }
1512 1512  
1513 1513          if ((t = pnp->pr_common->prc_thread) != NULL)
1514 1514                  prgetlwpsinfo(t, &lwpsinfo);
1515 1515          else {
1516 1516                  lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry;
1517 1517                  bzero(&lwpsinfo, sizeof (lwpsinfo));
1518 1518                  lwpsinfo.pr_lwpid = lep->le_lwpid;
1519 1519                  lwpsinfo.pr_state = SZOMB;
1520 1520                  lwpsinfo.pr_sname = 'Z';
1521 1521                  lwpsinfo.pr_start.tv_sec = lep->le_start;
1522 1522                  lwpsinfo.pr_bindpro = PBIND_NONE;
1523 1523                  lwpsinfo.pr_bindpset = PS_NONE;
1524 1524          }
1525 1525          prunlock(pnp);
1526 1526  
1527 1527          return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop));
1528 1528  }
1529 1529  
1530 1530  static int
1531 1531  pr_read_lwpusage(prnode_t *pnp, uio_t *uiop)
1532 1532  {
1533 1533          prhusage_t *pup;
1534 1534          prusage_t *upup;
1535 1535          proc_t *p;
1536 1536          int error;
1537 1537  
1538 1538          ASSERT(pnp->pr_type == PR_LWPUSAGE);
1539 1539  
1540 1540          /* allocate now, before locking the process */
1541 1541          pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
1542 1542          upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
1543 1543  
1544 1544          /*
1545 1545           * We don't want the full treatment of prlock(pnp) here.
1546 1546           * This file is world-readable and never goes invalid.
1547 1547           * It doesn't matter if we are in the middle of an exec().
1548 1548           */
1549 1549          p = pr_p_lock(pnp);
1550 1550          mutex_exit(&pr_pidlock);
1551 1551          if (p == NULL) {
1552 1552                  error = ENOENT;
1553 1553                  goto out;
1554 1554          }
1555 1555          ASSERT(p == pnp->pr_common->prc_proc);
1556 1556          if (pnp->pr_common->prc_thread == NULL) {
1557 1557                  prunlock(pnp);
1558 1558                  error = ENOENT;
1559 1559                  goto out;
1560 1560          }
1561 1561          if (uiop->uio_offset >= sizeof (prusage_t)) {
1562 1562                  prunlock(pnp);
1563 1563                  error = 0;
1564 1564                  goto out;
1565 1565          }
1566 1566  
1567 1567          pup->pr_tstamp = gethrtime();
1568 1568          prgetusage(pnp->pr_common->prc_thread, pup);
1569 1569  
1570 1570          prunlock(pnp);
1571 1571  
1572 1572          prcvtusage(pup, upup);
1573 1573  
1574 1574          error = pr_uioread(upup, sizeof (prusage_t), uiop);
1575 1575  out:
1576 1576          kmem_free(pup, sizeof (*pup));
1577 1577          kmem_free(upup, sizeof (*upup));
1578 1578          return (error);
1579 1579  }
1580 1580  
1581 1581  /* ARGSUSED */
1582 1582  static int
1583 1583  pr_read_xregs(prnode_t *pnp, uio_t *uiop)
1584 1584  {
1585 1585  #if defined(__sparc)
1586 1586          proc_t *p;
1587 1587          kthread_t *t;
1588 1588          int error;
1589 1589          char *xreg;
1590 1590          size_t size;
1591 1591  
1592 1592          ASSERT(pnp->pr_type == PR_XREGS);
1593 1593  
1594 1594          xreg = kmem_zalloc(sizeof (prxregset_t), KM_SLEEP);
1595 1595  
1596 1596          if ((error = prlock(pnp, ZNO)) != 0)
1597 1597                  goto out;
1598 1598  
1599 1599          p = pnp->pr_common->prc_proc;
1600 1600          t = pnp->pr_common->prc_thread;
1601 1601  
1602 1602          size = prhasx(p)? prgetprxregsize(p) : 0;
1603 1603          if (uiop->uio_offset >= size) {
1604 1604                  prunlock(pnp);
1605 1605                  goto out;
1606 1606          }
1607 1607  
1608 1608          /* drop p->p_lock while (possibly) touching the stack */
1609 1609          mutex_exit(&p->p_lock);
1610 1610          prgetprxregs(ttolwp(t), xreg);
1611 1611          mutex_enter(&p->p_lock);
1612 1612          prunlock(pnp);
1613 1613  
1614 1614          error = pr_uioread(xreg, size, uiop);
1615 1615  out:
1616 1616          kmem_free(xreg, sizeof (prxregset_t));
1617 1617          return (error);
1618 1618  #else
1619 1619          return (0);
1620 1620  #endif
1621 1621  }
1622 1622  
1623 1623  static int
1624 1624  pr_read_spymaster(prnode_t *pnp, uio_t *uiop)
1625 1625  {
1626 1626          psinfo_t psinfo;
1627 1627          int error;
1628 1628          klwp_t *lwp;
1629 1629  
1630 1630          ASSERT(pnp->pr_type == PR_SPYMASTER);
1631 1631  
1632 1632          if ((error = prlock(pnp, ZNO)) != 0)
1633 1633                  return (error);
1634 1634  
1635 1635          lwp = pnp->pr_common->prc_thread->t_lwp;
1636 1636  
1637 1637          if (lwp->lwp_spymaster == NULL) {
1638 1638                  prunlock(pnp);
1639 1639                  return (0);
1640 1640          }
1641 1641  
1642 1642          bcopy(lwp->lwp_spymaster, &psinfo, sizeof (psinfo_t));
1643 1643          prunlock(pnp);
1644 1644  
1645 1645          return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
1646 1646  }
1647 1647  
1648 1648  #if defined(__sparc)
1649 1649  
1650 1650  static int
1651 1651  pr_read_gwindows(prnode_t *pnp, uio_t *uiop)
1652 1652  {
1653 1653          proc_t *p;
1654 1654          kthread_t *t;
1655 1655          gwindows_t *gwp;
1656 1656          int error;
1657 1657          size_t size;
1658 1658  
1659 1659          ASSERT(pnp->pr_type == PR_GWINDOWS);
1660 1660  
1661 1661          gwp = kmem_zalloc(sizeof (gwindows_t), KM_SLEEP);
1662 1662  
1663 1663          if ((error = prlock(pnp, ZNO)) != 0)
1664 1664                  goto out;
1665 1665  
1666 1666          p = pnp->pr_common->prc_proc;
1667 1667          t = pnp->pr_common->prc_thread;
1668 1668  
1669 1669          /*
1670 1670           * Drop p->p_lock while touching the stack.
1671 1671           * The P_PR_LOCK flag prevents the lwp from
1672 1672           * disappearing while we do this.
1673 1673           */
1674 1674          mutex_exit(&p->p_lock);
1675 1675          if ((size = prnwindows(ttolwp(t))) != 0)
1676 1676                  size = sizeof (gwindows_t) -
1677 1677                      (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow);
1678 1678          if (uiop->uio_offset >= size) {
1679 1679                  mutex_enter(&p->p_lock);
1680 1680                  prunlock(pnp);
1681 1681                  goto out;
1682 1682          }
1683 1683          prgetwindows(ttolwp(t), gwp);
1684 1684          mutex_enter(&p->p_lock);
1685 1685          prunlock(pnp);
1686 1686  
1687 1687          error = pr_uioread(gwp, size, uiop);
1688 1688  out:
1689 1689          kmem_free(gwp, sizeof (gwindows_t));
1690 1690          return (error);
1691 1691  }
1692 1692  
1693 1693  /* ARGSUSED */
1694 1694  static int
1695 1695  pr_read_asrs(prnode_t *pnp, uio_t *uiop)
1696 1696  {
1697 1697          int error;
1698 1698  
1699 1699          ASSERT(pnp->pr_type == PR_ASRS);
1700 1700  
1701 1701          /* the asrs file exists only for sparc v9 _LP64 processes */
1702 1702          if ((error = prlock(pnp, ZNO)) == 0) {
1703 1703                  proc_t *p = pnp->pr_common->prc_proc;
1704 1704                  kthread_t *t = pnp->pr_common->prc_thread;
1705 1705                  asrset_t asrset;
1706 1706  
1707 1707                  if (p->p_model != DATAMODEL_LP64 ||
1708 1708                      uiop->uio_offset >= sizeof (asrset_t)) {
1709 1709                          prunlock(pnp);
1710 1710                          return (0);
1711 1711                  }
1712 1712  
1713 1713                  /*
1714 1714                   * Drop p->p_lock while touching the stack.
1715 1715                   * The P_PR_LOCK flag prevents the lwp from
1716 1716                   * disappearing while we do this.
1717 1717                   */
1718 1718                  mutex_exit(&p->p_lock);
1719 1719                  prgetasregs(ttolwp(t), asrset);
1720 1720                  mutex_enter(&p->p_lock);
1721 1721                  prunlock(pnp);
1722 1722  
1723 1723                  error = pr_uioread(&asrset[0], sizeof (asrset_t), uiop);
1724 1724          }
1725 1725  
1726 1726          return (error);
1727 1727  }
1728 1728  
1729 1729  #endif  /* __sparc */
1730 1730  
1731 1731  static int
1732 1732  pr_read_piddir(prnode_t *pnp, uio_t *uiop)
1733 1733  {
1734 1734          ASSERT(pnp->pr_type == PR_PIDDIR);
1735 1735          ASSERT(pnp->pr_pidfile != NULL);
1736 1736  
1737 1737          /* use the underlying PR_PIDFILE to read the process */
1738 1738          pnp = VTOP(pnp->pr_pidfile);
1739 1739          ASSERT(pnp->pr_type == PR_PIDFILE);
1740 1740  
1741 1741          return (pr_read_pidfile(pnp, uiop));
1742 1742  }
1743 1743  
1744 1744  static int
1745 1745  pr_read_pidfile(prnode_t *pnp, uio_t *uiop)
1746 1746  {
1747 1747          int error;
1748 1748  
1749 1749          ASSERT(pnp->pr_type == PR_PIDFILE || pnp->pr_type == PR_LWPIDFILE);
1750 1750  
1751 1751          if ((error = prlock(pnp, ZNO)) == 0) {
1752 1752                  proc_t *p = pnp->pr_common->prc_proc;
1753 1753                  struct as *as = p->p_as;
1754 1754  
1755 1755                  if ((p->p_flag & SSYS) || as == &kas) {
1756 1756                          /*
1757 1757                           * /proc I/O cannot be done to a system process.
1758 1758                           */
1759 1759                          error = EIO;    /* old /proc semantics */
1760 1760                  } else {
1761 1761                          /*
1762 1762                           * We drop p_lock because we don't want to hold
1763 1763                           * it over an I/O operation because that could
1764 1764                           * lead to deadlock with the clock thread.
1765 1765                           * The process will not disappear and its address
1766 1766                           * space will not change because it is marked P_PR_LOCK.
1767 1767                           */
1768 1768                          mutex_exit(&p->p_lock);
1769 1769                          error = prusrio(p, UIO_READ, uiop, 1);
1770 1770                          mutex_enter(&p->p_lock);
1771 1771                  }
1772 1772                  prunlock(pnp);
1773 1773          }
1774 1774  
1775 1775          return (error);
1776 1776  }
1777 1777  
1778 1778  #ifdef _SYSCALL32_IMPL
1779 1779  
1780 1780  /*
1781 1781   * Array of ILP32 read functions, indexed by /proc file type.
1782 1782   */
1783 1783  static int pr_read_status_32(),
1784 1784          pr_read_lstatus_32(), pr_read_psinfo_32(), pr_read_lpsinfo_32(),
1785 1785          pr_read_map_32(), pr_read_rmap_32(), pr_read_xmap_32(),
1786 1786          pr_read_sigact_32(), pr_read_auxv_32(),
1787 1787          pr_read_usage_32(), pr_read_lusage_32(), pr_read_pagedata_32(),
1788 1788          pr_read_watch_32(), pr_read_lwpstatus_32(), pr_read_lwpsinfo_32(),
1789 1789          pr_read_lwpusage_32(), pr_read_spymaster_32(),
1790 1790  #if defined(__sparc)
1791 1791          pr_read_gwindows_32(),
1792 1792  #endif
1793 1793          pr_read_opagedata_32();
1794 1794  
1795 1795  static int (*pr_read_function_32[PR_NFILES])() = {
1796 1796          pr_read_inval,          /* /proc                                */
1797 1797          pr_read_inval,          /* /proc/self                           */
1798 1798          pr_read_piddir,         /* /proc/<pid> (old /proc read())       */
1799 1799          pr_read_as,             /* /proc/<pid>/as                       */
1800 1800          pr_read_inval,          /* /proc/<pid>/ctl                      */
1801 1801          pr_read_status_32,      /* /proc/<pid>/status                   */
1802 1802          pr_read_lstatus_32,     /* /proc/<pid>/lstatus                  */
1803 1803          pr_read_psinfo_32,      /* /proc/<pid>/psinfo                   */
1804 1804          pr_read_lpsinfo_32,     /* /proc/<pid>/lpsinfo                  */
1805 1805          pr_read_map_32,         /* /proc/<pid>/map                      */
1806 1806          pr_read_rmap_32,        /* /proc/<pid>/rmap                     */
1807 1807          pr_read_xmap_32,        /* /proc/<pid>/xmap                     */
1808 1808          pr_read_cred,           /* /proc/<pid>/cred                     */
1809 1809          pr_read_sigact_32,      /* /proc/<pid>/sigact                   */
1810 1810          pr_read_auxv_32,        /* /proc/<pid>/auxv                     */
1811 1811  #if defined(__x86)
1812 1812          pr_read_ldt,            /* /proc/<pid>/ldt                      */
1813 1813  #endif
1814 1814          pr_read_argv,           /* /proc/<pid>/argv                     */
1815 1815          pr_read_usage_32,       /* /proc/<pid>/usage                    */
1816 1816          pr_read_lusage_32,      /* /proc/<pid>/lusage                   */
1817 1817          pr_read_pagedata_32,    /* /proc/<pid>/pagedata                 */
1818 1818          pr_read_watch_32,       /* /proc/<pid>/watch                    */
1819 1819          pr_read_inval,          /* /proc/<pid>/cwd                      */
1820 1820          pr_read_inval,          /* /proc/<pid>/root                     */
1821 1821          pr_read_inval,          /* /proc/<pid>/fd                       */
1822 1822          pr_read_inval,          /* /proc/<pid>/fd/nn                    */
1823 1823          pr_read_inval,          /* /proc/<pid>/object                   */
1824 1824          pr_read_inval,          /* /proc/<pid>/object/xxx               */
1825 1825          pr_read_inval,          /* /proc/<pid>/lwp                      */
1826 1826          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>              */
1827 1827          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl       */
1828 1828          pr_read_lwpstatus_32,   /* /proc/<pid>/lwp/<lwpid>/lwpstatus    */
1829 1829          pr_read_lwpsinfo_32,    /* /proc/<pid>/lwp/<lwpid>/lwpsinfo     */
1830 1830          pr_read_lwpusage_32,    /* /proc/<pid>/lwp/<lwpid>/lwpusage     */
1831 1831          pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs        */
1832 1832          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates    */
1833 1833          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1834 1834          pr_read_spymaster_32,   /* /proc/<pid>/lwp/<lwpid>/spymaster    */
1835 1835  #if defined(__sparc)
1836 1836          pr_read_gwindows_32,    /* /proc/<pid>/lwp/<lwpid>/gwindows     */
1837 1837          pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs         */
1838 1838  #endif
1839 1839          pr_read_priv,           /* /proc/<pid>/priv                     */
1840 1840          pr_read_inval,          /* /proc/<pid>/path                     */
1841 1841          pr_read_inval,          /* /proc/<pid>/path/xxx                 */
1842 1842          pr_read_inval,          /* /proc/<pid>/contracts                */
1843 1843          pr_read_inval,          /* /proc/<pid>/contracts/<ctid>         */
1844 1844          pr_read_pidfile,        /* old process file                     */
1845 1845          pr_read_pidfile,        /* old lwp file                         */
1846 1846          pr_read_opagedata_32,   /* old pagedata file                    */
1847 1847  };
1848 1848  
1849 1849  static int
1850 1850  pr_read_status_32(prnode_t *pnp, uio_t *uiop)
1851 1851  {
1852 1852          pstatus32_t *sp;
1853 1853          proc_t *p;
1854 1854          int error;
1855 1855  
1856 1856          ASSERT(pnp->pr_type == PR_STATUS);
1857 1857  
1858 1858          /*
1859 1859           * We kmem_alloc() the pstatus structure because
1860 1860           * it is so big it might blow the kernel stack.
1861 1861           */
1862 1862          sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
1863 1863          if ((error = prlock(pnp, ZNO)) == 0) {
1864 1864                  /*
1865 1865                   * A 32-bit process cannot get the status of a 64-bit process.
1866 1866                   * The fields for the 64-bit quantities are not large enough.
1867 1867                   */
1868 1868                  p = pnp->pr_common->prc_proc;
1869 1869                  if (PROCESS_NOT_32BIT(p)) {
1870 1870                          prunlock(pnp);
1871 1871                          error = EOVERFLOW;
1872 1872                  } else {
1873 1873                          prgetstatus32(pnp->pr_common->prc_proc, sp,
1874 1874                              VTOZONE(PTOV(pnp)));
1875 1875                          prunlock(pnp);
1876 1876                          error = pr_uioread(sp, sizeof (*sp), uiop);
1877 1877                  }
1878 1878          }
1879 1879          kmem_free((caddr_t)sp, sizeof (*sp));
1880 1880          return (error);
1881 1881  }
1882 1882  
1883 1883  static int
1884 1884  pr_read_lstatus_32(prnode_t *pnp, uio_t *uiop)
1885 1885  {
1886 1886          proc_t *p;
1887 1887          kthread_t *t;
1888 1888          lwpdir_t *ldp;
1889 1889          size_t size;
1890 1890          prheader32_t *php;
1891 1891          lwpstatus32_t *sp;
1892 1892          int error;
1893 1893          int nlwp;
1894 1894          int i;
1895 1895  
1896 1896          ASSERT(pnp->pr_type == PR_LSTATUS);
1897 1897  
1898 1898          if ((error = prlock(pnp, ZNO)) != 0)
1899 1899                  return (error);
1900 1900          p = pnp->pr_common->prc_proc;
1901 1901          /*
1902 1902           * A 32-bit process cannot get the status of a 64-bit process.
1903 1903           * The fields for the 64-bit quantities are not large enough.
1904 1904           */
1905 1905          if (PROCESS_NOT_32BIT(p)) {
1906 1906                  prunlock(pnp);
1907 1907                  return (EOVERFLOW);
1908 1908          }
1909 1909          nlwp = p->p_lwpcnt;
1910 1910          size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpstatus32_t);
1911 1911  
1912 1912          /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1913 1913          mutex_exit(&p->p_lock);
1914 1914          php = kmem_zalloc(size, KM_SLEEP);
1915 1915          mutex_enter(&p->p_lock);
1916 1916          /* p->p_lwpcnt can't change while process is locked */
1917 1917          ASSERT(nlwp == p->p_lwpcnt);
1918 1918  
1919 1919          php->pr_nent = nlwp;
1920 1920          php->pr_entsize = LSPAN32(lwpstatus32_t);
1921 1921  
1922 1922          sp = (lwpstatus32_t *)(php + 1);
1923 1923          for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1924 1924                  if (ldp->ld_entry == NULL ||
1925 1925                      (t = ldp->ld_entry->le_thread) == NULL)
1926 1926                          continue;
1927 1927                  prgetlwpstatus32(t, sp, VTOZONE(PTOV(pnp)));
1928 1928                  sp = (lwpstatus32_t *)((caddr_t)sp + LSPAN32(lwpstatus32_t));
1929 1929          }
1930 1930          prunlock(pnp);
1931 1931  
1932 1932          error = pr_uioread(php, size, uiop);
1933 1933          kmem_free(php, size);
1934 1934          return (error);
1935 1935  }
1936 1936  
1937 1937  static int
1938 1938  pr_read_psinfo_32(prnode_t *pnp, uio_t *uiop)
1939 1939  {
1940 1940          psinfo32_t psinfo;
1941 1941          proc_t *p;
1942 1942          int error = 0;
1943 1943  
1944 1944          ASSERT(pnp->pr_type == PR_PSINFO);
1945 1945  
1946 1946          /*
1947 1947           * We don't want the full treatment of prlock(pnp) here.
1948 1948           * This file is world-readable and never goes invalid.
1949 1949           * It doesn't matter if we are in the middle of an exec().
1950 1950           */
1951 1951          p = pr_p_lock(pnp);
1952 1952          mutex_exit(&pr_pidlock);
1953 1953          if (p == NULL)
1954 1954                  error = ENOENT;
1955 1955          else {
1956 1956                  ASSERT(p == pnp->pr_common->prc_proc);
1957 1957                  prgetpsinfo32(p, &psinfo);
1958 1958                  prunlock(pnp);
1959 1959                  error = pr_uioread(&psinfo, sizeof (psinfo), uiop);
1960 1960          }
1961 1961          return (error);
1962 1962  }
1963 1963  
1964 1964  static int
1965 1965  pr_read_lpsinfo_32(prnode_t *pnp, uio_t *uiop)
1966 1966  {
1967 1967          proc_t *p;
1968 1968          kthread_t *t;
1969 1969          lwpdir_t *ldp;
1970 1970          lwpent_t *lep;
1971 1971          size_t size;
1972 1972          prheader32_t *php;
1973 1973          lwpsinfo32_t *sp;
1974 1974          int error;
1975 1975          int nlwp;
1976 1976          int i;
1977 1977  
1978 1978          ASSERT(pnp->pr_type == PR_LPSINFO);
1979 1979  
1980 1980          /*
1981 1981           * We don't want the full treatment of prlock(pnp) here.
1982 1982           * This file is world-readable and never goes invalid.
1983 1983           * It doesn't matter if we are in the middle of an exec().
1984 1984           */
1985 1985          p = pr_p_lock(pnp);
1986 1986          mutex_exit(&pr_pidlock);
1987 1987          if (p == NULL)
1988 1988                  return (ENOENT);
1989 1989          ASSERT(p == pnp->pr_common->prc_proc);
1990 1990          if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) {
1991 1991                  prunlock(pnp);
1992 1992                  return (ENOENT);
1993 1993          }
1994 1994          size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpsinfo32_t);
1995 1995  
1996 1996          /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1997 1997          mutex_exit(&p->p_lock);
1998 1998          php = kmem_zalloc(size, KM_SLEEP);
1999 1999          mutex_enter(&p->p_lock);
2000 2000          /* p->p_lwpcnt can't change while process is locked */
2001 2001          ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt);
2002 2002  
2003 2003          php->pr_nent = nlwp;
2004 2004          php->pr_entsize = LSPAN32(lwpsinfo32_t);
2005 2005  
2006 2006          sp = (lwpsinfo32_t *)(php + 1);
2007 2007          for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
2008 2008                  if ((lep = ldp->ld_entry) == NULL)
2009 2009                          continue;
2010 2010                  if ((t = lep->le_thread) != NULL)
2011 2011                          prgetlwpsinfo32(t, sp);
2012 2012                  else {
2013 2013                          bzero(sp, sizeof (*sp));
2014 2014                          sp->pr_lwpid = lep->le_lwpid;
2015 2015                          sp->pr_state = SZOMB;
2016 2016                          sp->pr_sname = 'Z';
2017 2017                          sp->pr_start.tv_sec = (time32_t)lep->le_start;
2018 2018                  }
2019 2019                  sp = (lwpsinfo32_t *)((caddr_t)sp + LSPAN32(lwpsinfo32_t));
2020 2020          }
2021 2021          prunlock(pnp);
2022 2022  
2023 2023          error = pr_uioread(php, size, uiop);
2024 2024          kmem_free(php, size);
2025 2025          return (error);
2026 2026  }
2027 2027  
2028 2028  static int
2029 2029  pr_read_map_common_32(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
2030 2030  {
2031 2031          proc_t *p;
2032 2032          struct as *as;
2033 2033          list_t  iolhead;
2034 2034          int error;
2035 2035  
2036 2036  readmap32_common:
2037 2037          if ((error = prlock(pnp, ZNO)) != 0)
2038 2038                  return (error);
2039 2039  
2040 2040          p = pnp->pr_common->prc_proc;
2041 2041          as = p->p_as;
2042 2042  
2043 2043          if ((p->p_flag & SSYS) || as == &kas) {
2044 2044                  prunlock(pnp);
2045 2045                  return (0);
2046 2046          }
2047 2047  
2048 2048          if (PROCESS_NOT_32BIT(p)) {
2049 2049                  prunlock(pnp);
2050 2050                  return (EOVERFLOW);
2051 2051          }
2052 2052  
2053 2053          if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
2054 2054                  prunlock(pnp);
2055 2055                  delay(1);
2056 2056                  goto readmap32_common;
2057 2057          }
2058 2058          mutex_exit(&p->p_lock);
2059 2059  
2060 2060          switch (type) {
2061 2061          case PR_XMAP:
2062 2062                  error = prgetxmap32(p, &iolhead);
2063 2063                  break;
2064 2064          case PR_RMAP:
2065 2065                  error = prgetmap32(p, 1, &iolhead);
2066 2066                  break;
2067 2067          case PR_MAP:
2068 2068                  error = prgetmap32(p, 0, &iolhead);
2069 2069                  break;
2070 2070          }
2071 2071          AS_LOCK_EXIT(as);
2072 2072          mutex_enter(&p->p_lock);
2073 2073          prunlock(pnp);
2074 2074  
2075 2075          error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
2076 2076  
2077 2077          return (error);
2078 2078  }
2079 2079  
2080 2080  static int
2081 2081  pr_read_map_32(prnode_t *pnp, uio_t *uiop)
2082 2082  {
2083 2083          ASSERT(pnp->pr_type == PR_MAP);
2084 2084          return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2085 2085  }
2086 2086  
2087 2087  static int
2088 2088  pr_read_rmap_32(prnode_t *pnp, uio_t *uiop)
2089 2089  {
2090 2090          ASSERT(pnp->pr_type == PR_RMAP);
2091 2091          return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2092 2092  }
2093 2093  
2094 2094  static int
2095 2095  pr_read_xmap_32(prnode_t *pnp, uio_t *uiop)
2096 2096  {
2097 2097          ASSERT(pnp->pr_type == PR_XMAP);
2098 2098          return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2099 2099  }
2100 2100  
2101 2101  static int
2102 2102  pr_read_sigact_32(prnode_t *pnp, uio_t *uiop)
2103 2103  {
2104 2104          int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
2105 2105          proc_t *p;
2106 2106          struct sigaction32 *sap;
2107 2107          int sig;
2108 2108          int error;
2109 2109          user_t *up;
2110 2110  
2111 2111          ASSERT(pnp->pr_type == PR_SIGACT);
2112 2112  
2113 2113          /*
2114 2114           * We kmem_alloc() the sigaction32 array because
2115 2115           * it is so big it might blow the kernel stack.
2116 2116           */
2117 2117          sap = kmem_alloc((nsig-1) * sizeof (struct sigaction32), KM_SLEEP);
2118 2118  
2119 2119          if ((error = prlock(pnp, ZNO)) != 0)
2120 2120                  goto out;
2121 2121          p = pnp->pr_common->prc_proc;
2122 2122  
2123 2123          if (PROCESS_NOT_32BIT(p)) {
2124 2124                  prunlock(pnp);
2125 2125                  error = EOVERFLOW;
2126 2126                  goto out;
2127 2127          }
2128 2128  
2129 2129          if (uiop->uio_offset >= (nsig-1) * sizeof (struct sigaction32)) {
2130 2130                  prunlock(pnp);
2131 2131                  goto out;
2132 2132          }
2133 2133  
2134 2134          up = PTOU(p);
2135 2135          for (sig = 1; sig < nsig; sig++)
2136 2136                  prgetaction32(p, up, sig, &sap[sig-1]);
2137 2137          prunlock(pnp);
2138 2138  
2139 2139          error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction32), uiop);
2140 2140  out:
2141 2141          kmem_free(sap, (nsig-1) * sizeof (struct sigaction32));
2142 2142          return (error);
2143 2143  }
2144 2144  
2145 2145  static int
2146 2146  pr_read_auxv_32(prnode_t *pnp, uio_t *uiop)
2147 2147  {
2148 2148          auxv32_t auxv[__KERN_NAUXV_IMPL];
2149 2149          proc_t *p;
2150 2150          user_t *up;
2151 2151          int error;
2152 2152          int i;
2153 2153  
2154 2154          ASSERT(pnp->pr_type == PR_AUXV);
2155 2155  
2156 2156          if ((error = prlock(pnp, ZNO)) != 0)
2157 2157                  return (error);
2158 2158          p = pnp->pr_common->prc_proc;
2159 2159  
2160 2160          if (PROCESS_NOT_32BIT(p)) {
2161 2161                  prunlock(pnp);
2162 2162                  return (EOVERFLOW);
2163 2163          }
2164 2164  
2165 2165          if (uiop->uio_offset >= sizeof (auxv)) {
2166 2166                  prunlock(pnp);
2167 2167                  return (0);
2168 2168          }
2169 2169  
2170 2170          up = PTOU(p);
2171 2171          for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
2172 2172                  auxv[i].a_type = (int32_t)up->u_auxv[i].a_type;
2173 2173                  auxv[i].a_un.a_val = (int32_t)up->u_auxv[i].a_un.a_val;
2174 2174          }
2175 2175          prunlock(pnp);
2176 2176  
2177 2177          return (pr_uioread(auxv, sizeof (auxv), uiop));
2178 2178  }
2179 2179  
2180 2180  static int
2181 2181  pr_read_usage_32(prnode_t *pnp, uio_t *uiop)
2182 2182  {
2183 2183          prhusage_t *pup;
2184 2184          prusage32_t *upup;
2185 2185          proc_t *p;
2186 2186          kthread_t *t;
2187 2187          int error;
2188 2188  
2189 2189          ASSERT(pnp->pr_type == PR_USAGE);
2190 2190  
2191 2191          /* allocate now, before locking the process */
2192 2192          pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
2193 2193          upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
2194 2194  
2195 2195          /*
2196 2196           * We don't want the full treatment of prlock(pnp) here.
2197 2197           * This file is world-readable and never goes invalid.
2198 2198           * It doesn't matter if we are in the middle of an exec().
2199 2199           */
2200 2200          p = pr_p_lock(pnp);
2201 2201          mutex_exit(&pr_pidlock);
2202 2202          if (p == NULL) {
2203 2203                  error = ENOENT;
2204 2204                  goto out;
2205 2205          }
2206 2206          ASSERT(p == pnp->pr_common->prc_proc);
2207 2207  
2208 2208          if (uiop->uio_offset >= sizeof (prusage32_t)) {
2209 2209                  prunlock(pnp);
2210 2210                  error = 0;
2211 2211                  goto out;
2212 2212          }
2213 2213  
2214 2214          pup->pr_tstamp = gethrtime();
2215 2215  
2216 2216          pup->pr_count  = p->p_defunct;
2217 2217          pup->pr_create = p->p_mstart;
2218 2218          pup->pr_term   = p->p_mterm;
2219 2219  
2220 2220          pup->pr_rtime    = p->p_mlreal;
2221 2221          pup->pr_utime    = p->p_acct[LMS_USER];
2222 2222          pup->pr_stime    = p->p_acct[LMS_SYSTEM];
2223 2223          pup->pr_ttime    = p->p_acct[LMS_TRAP];
2224 2224          pup->pr_tftime   = p->p_acct[LMS_TFAULT];
2225 2225          pup->pr_dftime   = p->p_acct[LMS_DFAULT];
2226 2226          pup->pr_kftime   = p->p_acct[LMS_KFAULT];
2227 2227          pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
2228 2228          pup->pr_slptime  = p->p_acct[LMS_SLEEP];
2229 2229          pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
2230 2230          pup->pr_stoptime = p->p_acct[LMS_STOPPED];
2231 2231  
2232 2232          pup->pr_minf  = p->p_ru.minflt;
2233 2233          pup->pr_majf  = p->p_ru.majflt;
2234 2234          pup->pr_nswap = p->p_ru.nswap;
2235 2235          pup->pr_inblk = p->p_ru.inblock;
2236 2236          pup->pr_oublk = p->p_ru.oublock;
2237 2237          pup->pr_msnd  = p->p_ru.msgsnd;
2238 2238          pup->pr_mrcv  = p->p_ru.msgrcv;
2239 2239          pup->pr_sigs  = p->p_ru.nsignals;
2240 2240          pup->pr_vctx  = p->p_ru.nvcsw;
2241 2241          pup->pr_ictx  = p->p_ru.nivcsw;
2242 2242          pup->pr_sysc  = p->p_ru.sysc;
2243 2243          pup->pr_ioch  = p->p_ru.ioch;
2244 2244  
2245 2245          /*
2246 2246           * Add the usage information for each active lwp.
2247 2247           */
2248 2248          if ((t = p->p_tlist) != NULL &&
2249 2249              !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) {
2250 2250                  do {
2251 2251                          if (t->t_proc_flag & TP_LWPEXIT)
2252 2252                                  continue;
2253 2253                          pup->pr_count++;
2254 2254                          praddusage(t, pup);
2255 2255                  } while ((t = t->t_forw) != p->p_tlist);
2256 2256          }
2257 2257  
2258 2258          prunlock(pnp);
2259 2259  
2260 2260          prcvtusage32(pup, upup);
2261 2261  
2262 2262          error = pr_uioread(upup, sizeof (prusage32_t), uiop);
2263 2263  out:
2264 2264          kmem_free(pup, sizeof (*pup));
2265 2265          kmem_free(upup, sizeof (*upup));
2266 2266          return (error);
2267 2267  }
2268 2268  
2269 2269  static int
2270 2270  pr_read_lusage_32(prnode_t *pnp, uio_t *uiop)
2271 2271  {
2272 2272          int nlwp;
2273 2273          prhusage_t *pup;
2274 2274          prheader32_t *php;
2275 2275          prusage32_t *upup;
2276 2276          size_t size;
2277 2277          hrtime_t curtime;
2278 2278          proc_t *p;
2279 2279          kthread_t *t;
2280 2280          lwpdir_t *ldp;
2281 2281          int error;
2282 2282          int i;
2283 2283  
2284 2284          ASSERT(pnp->pr_type == PR_LUSAGE);
2285 2285  
2286 2286          /*
2287 2287           * We don't want the full treatment of prlock(pnp) here.
2288 2288           * This file is world-readable and never goes invalid.
2289 2289           * It doesn't matter if we are in the middle of an exec().
2290 2290           */
2291 2291          p = pr_p_lock(pnp);
2292 2292          mutex_exit(&pr_pidlock);
2293 2293          if (p == NULL)
2294 2294                  return (ENOENT);
2295 2295          ASSERT(p == pnp->pr_common->prc_proc);
2296 2296          if ((nlwp = p->p_lwpcnt) == 0) {
2297 2297                  prunlock(pnp);
2298 2298                  return (ENOENT);
2299 2299          }
2300 2300  
2301 2301          size = sizeof (prheader32_t) + (nlwp + 1) * LSPAN32(prusage32_t);
2302 2302          if (uiop->uio_offset >= size) {
2303 2303                  prunlock(pnp);
2304 2304                  return (0);
2305 2305          }
2306 2306  
2307 2307          /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2308 2308          mutex_exit(&p->p_lock);
2309 2309          pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP);
2310 2310          mutex_enter(&p->p_lock);
2311 2311          /* p->p_lwpcnt can't change while process is locked */
2312 2312          ASSERT(nlwp == p->p_lwpcnt);
2313 2313  
2314 2314          php = (prheader32_t *)(pup + 1);
2315 2315          upup = (prusage32_t *)(php + 1);
2316 2316  
2317 2317          php->pr_nent = nlwp + 1;
2318 2318          php->pr_entsize = LSPAN32(prusage32_t);
2319 2319  
2320 2320          curtime = gethrtime();
2321 2321  
2322 2322          /*
2323 2323           * First the summation over defunct lwps.
2324 2324           */
2325 2325          pup->pr_count  = p->p_defunct;
2326 2326          pup->pr_tstamp = curtime;
2327 2327          pup->pr_create = p->p_mstart;
2328 2328          pup->pr_term   = p->p_mterm;
2329 2329  
2330 2330          pup->pr_rtime    = p->p_mlreal;
2331 2331          pup->pr_utime    = p->p_acct[LMS_USER];
2332 2332          pup->pr_stime    = p->p_acct[LMS_SYSTEM];
2333 2333          pup->pr_ttime    = p->p_acct[LMS_TRAP];
2334 2334          pup->pr_tftime   = p->p_acct[LMS_TFAULT];
2335 2335          pup->pr_dftime   = p->p_acct[LMS_DFAULT];
2336 2336          pup->pr_kftime   = p->p_acct[LMS_KFAULT];
2337 2337          pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
2338 2338          pup->pr_slptime  = p->p_acct[LMS_SLEEP];
2339 2339          pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
2340 2340          pup->pr_stoptime = p->p_acct[LMS_STOPPED];
2341 2341  
2342 2342          pup->pr_minf  = p->p_ru.minflt;
2343 2343          pup->pr_majf  = p->p_ru.majflt;
2344 2344          pup->pr_nswap = p->p_ru.nswap;
2345 2345          pup->pr_inblk = p->p_ru.inblock;
2346 2346          pup->pr_oublk = p->p_ru.oublock;
2347 2347          pup->pr_msnd  = p->p_ru.msgsnd;
2348 2348          pup->pr_mrcv  = p->p_ru.msgrcv;
2349 2349          pup->pr_sigs  = p->p_ru.nsignals;
2350 2350          pup->pr_vctx  = p->p_ru.nvcsw;
2351 2351          pup->pr_ictx  = p->p_ru.nivcsw;
2352 2352          pup->pr_sysc  = p->p_ru.sysc;
2353 2353          pup->pr_ioch  = p->p_ru.ioch;
2354 2354  
2355 2355          prcvtusage32(pup, upup);
2356 2356  
2357 2357          /*
2358 2358           * Fill one prusage struct for each active lwp.
2359 2359           */
2360 2360          for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
2361 2361                  if (ldp->ld_entry == NULL ||
2362 2362                      (t = ldp->ld_entry->le_thread) == NULL)
2363 2363                          continue;
2364 2364                  ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
2365 2365                  ASSERT(nlwp > 0);
2366 2366                  --nlwp;
2367 2367                  upup = (prusage32_t *)
2368 2368                      ((caddr_t)upup + LSPAN32(prusage32_t));
2369 2369                  prgetusage(t, pup);
2370 2370                  prcvtusage32(pup, upup);
2371 2371          }
2372 2372          ASSERT(nlwp == 0);
2373 2373  
2374 2374          prunlock(pnp);
2375 2375  
2376 2376          error = pr_uioread(php, size, uiop);
2377 2377          kmem_free(pup, size + sizeof (prhusage_t));
2378 2378          return (error);
2379 2379  }
2380 2380  
2381 2381  static int
2382 2382  pr_read_pagedata_32(prnode_t *pnp, uio_t *uiop)
2383 2383  {
2384 2384          proc_t *p;
2385 2385          int error;
2386 2386  
2387 2387          ASSERT(pnp->pr_type == PR_PAGEDATA);
2388 2388  
2389 2389          if ((error = prlock(pnp, ZNO)) != 0)
2390 2390                  return (error);
2391 2391  
2392 2392          p = pnp->pr_common->prc_proc;
2393 2393          if ((p->p_flag & SSYS) || p->p_as == &kas) {
2394 2394                  prunlock(pnp);
2395 2395                  return (0);
2396 2396          }
2397 2397  
2398 2398          if (PROCESS_NOT_32BIT(p)) {
2399 2399                  prunlock(pnp);
2400 2400                  return (EOVERFLOW);
2401 2401          }
2402 2402  
2403 2403          mutex_exit(&p->p_lock);
2404 2404          error = prpdread32(p, pnp->pr_hatid, uiop);
2405 2405          mutex_enter(&p->p_lock);
2406 2406  
2407 2407          prunlock(pnp);
2408 2408          return (error);
2409 2409  }
2410 2410  
2411 2411  static int
2412 2412  pr_read_opagedata_32(prnode_t *pnp, uio_t *uiop)
2413 2413  {
2414 2414          proc_t *p;
2415 2415          struct as *as;
2416 2416          int error;
2417 2417  
2418 2418          ASSERT(pnp->pr_type == PR_OPAGEDATA);
2419 2419  
2420 2420          if ((error = prlock(pnp, ZNO)) != 0)
2421 2421                  return (error);
2422 2422  
2423 2423          p = pnp->pr_common->prc_proc;
2424 2424          as = p->p_as;
2425 2425  
2426 2426          if ((p->p_flag & SSYS) || as == &kas) {
2427 2427                  prunlock(pnp);
2428 2428                  return (0);
2429 2429          }
2430 2430  
2431 2431          if (PROCESS_NOT_32BIT(p)) {
2432 2432                  prunlock(pnp);
2433 2433                  return (EOVERFLOW);
2434 2434          }
2435 2435  
2436 2436          mutex_exit(&p->p_lock);
2437 2437          error = oprpdread32(as, pnp->pr_hatid, uiop);
2438 2438          mutex_enter(&p->p_lock);
2439 2439  
2440 2440          prunlock(pnp);
2441 2441          return (error);
2442 2442  }
2443 2443  
2444 2444  static int
2445 2445  pr_read_watch_32(prnode_t *pnp, uio_t *uiop)
2446 2446  {
2447 2447          proc_t *p;
2448 2448          int error;
2449 2449          prwatch32_t *Bpwp;
2450 2450          size_t size;
2451 2451          prwatch32_t *pwp;
2452 2452          int nwarea;
2453 2453          struct watched_area *pwarea;
2454 2454  
2455 2455          ASSERT(pnp->pr_type == PR_WATCH);
2456 2456  
2457 2457          if ((error = prlock(pnp, ZNO)) != 0)
2458 2458                  return (error);
2459 2459  
2460 2460          p = pnp->pr_common->prc_proc;
2461 2461          if (PROCESS_NOT_32BIT(p)) {
2462 2462                  prunlock(pnp);
2463 2463                  return (EOVERFLOW);
2464 2464          }
2465 2465          nwarea = avl_numnodes(&p->p_warea);
2466 2466          size = nwarea * sizeof (prwatch32_t);
2467 2467          if (uiop->uio_offset >= size) {
2468 2468                  prunlock(pnp);
2469 2469                  return (0);
2470 2470          }
2471 2471  
2472 2472          /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2473 2473          mutex_exit(&p->p_lock);
2474 2474          Bpwp = pwp = kmem_zalloc(size, KM_SLEEP);
2475 2475          mutex_enter(&p->p_lock);
2476 2476          /* p->p_nwarea can't change while process is locked */
2477 2477          ASSERT(nwarea == avl_numnodes(&p->p_warea));
2478 2478  
2479 2479          /* gather the watched areas */
2480 2480          for (pwarea = avl_first(&p->p_warea); pwarea != NULL;
2481 2481              pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) {
2482 2482                  pwp->pr_vaddr = (caddr32_t)(uintptr_t)pwarea->wa_vaddr;
2483 2483                  pwp->pr_size = (size32_t)(pwarea->wa_eaddr - pwarea->wa_vaddr);
2484 2484                  pwp->pr_wflags = (int)pwarea->wa_flags;
2485 2485          }
2486 2486  
2487 2487          prunlock(pnp);
2488 2488  
2489 2489          error = pr_uioread(Bpwp, size, uiop);
2490 2490          kmem_free(Bpwp, size);
2491 2491          return (error);
2492 2492  }
2493 2493  
2494 2494  static int
2495 2495  pr_read_lwpstatus_32(prnode_t *pnp, uio_t *uiop)
2496 2496  {
2497 2497          lwpstatus32_t *sp;
2498 2498          proc_t *p;
2499 2499          int error;
2500 2500  
2501 2501          ASSERT(pnp->pr_type == PR_LWPSTATUS);
2502 2502  
2503 2503          /*
2504 2504           * We kmem_alloc() the lwpstatus structure because
2505 2505           * it is so big it might blow the kernel stack.
2506 2506           */
2507 2507          sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
2508 2508  
2509 2509          if ((error = prlock(pnp, ZNO)) != 0)
2510 2510                  goto out;
2511 2511  
2512 2512          /*
2513 2513           * A 32-bit process cannot get the status of a 64-bit process.
2514 2514           * The fields for the 64-bit quantities are not large enough.
2515 2515           */
2516 2516          p = pnp->pr_common->prc_proc;
2517 2517          if (PROCESS_NOT_32BIT(p)) {
2518 2518                  prunlock(pnp);
2519 2519                  error = EOVERFLOW;
2520 2520                  goto out;
2521 2521          }
2522 2522  
2523 2523          if (uiop->uio_offset >= sizeof (*sp)) {
2524 2524                  prunlock(pnp);
2525 2525                  goto out;
2526 2526          }
2527 2527  
2528 2528          prgetlwpstatus32(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp)));
2529 2529          prunlock(pnp);
2530 2530  
2531 2531          error = pr_uioread(sp, sizeof (*sp), uiop);
2532 2532  out:
2533 2533          kmem_free(sp, sizeof (*sp));
2534 2534          return (error);
2535 2535  }
2536 2536  
2537 2537  static int
2538 2538  pr_read_lwpsinfo_32(prnode_t *pnp, uio_t *uiop)
2539 2539  {
2540 2540          lwpsinfo32_t lwpsinfo;
2541 2541          proc_t *p;
2542 2542          kthread_t *t;
2543 2543          lwpent_t *lep;
2544 2544  
2545 2545          ASSERT(pnp->pr_type == PR_LWPSINFO);
2546 2546  
2547 2547          /*
2548 2548           * We don't want the full treatment of prlock(pnp) here.
2549 2549           * This file is world-readable and never goes invalid.
2550 2550           * It doesn't matter if we are in the middle of an exec().
2551 2551           */
2552 2552          p = pr_p_lock(pnp);
2553 2553          mutex_exit(&pr_pidlock);
2554 2554          if (p == NULL)
2555 2555                  return (ENOENT);
2556 2556          ASSERT(p == pnp->pr_common->prc_proc);
2557 2557          if (pnp->pr_common->prc_tslot == -1) {
2558 2558                  prunlock(pnp);
2559 2559                  return (ENOENT);
2560 2560          }
2561 2561  
2562 2562          if (uiop->uio_offset >= sizeof (lwpsinfo)) {
2563 2563                  prunlock(pnp);
2564 2564                  return (0);
2565 2565          }
2566 2566  
2567 2567          if ((t = pnp->pr_common->prc_thread) != NULL)
2568 2568                  prgetlwpsinfo32(t, &lwpsinfo);
2569 2569          else {
2570 2570                  lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry;
2571 2571                  bzero(&lwpsinfo, sizeof (lwpsinfo));
2572 2572                  lwpsinfo.pr_lwpid = lep->le_lwpid;
2573 2573                  lwpsinfo.pr_state = SZOMB;
2574 2574                  lwpsinfo.pr_sname = 'Z';
2575 2575                  lwpsinfo.pr_start.tv_sec = (time32_t)lep->le_start;
2576 2576          }
2577 2577          prunlock(pnp);
2578 2578  
2579 2579          return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop));
2580 2580  }
2581 2581  
2582 2582  static int
2583 2583  pr_read_lwpusage_32(prnode_t *pnp, uio_t *uiop)
2584 2584  {
2585 2585          prhusage_t *pup;
2586 2586          prusage32_t *upup;
2587 2587          proc_t *p;
2588 2588          int error;
2589 2589  
2590 2590          ASSERT(pnp->pr_type == PR_LWPUSAGE);
2591 2591  
2592 2592          /* allocate now, before locking the process */
2593 2593          pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
2594 2594          upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
2595 2595  
2596 2596          /*
2597 2597           * We don't want the full treatment of prlock(pnp) here.
2598 2598           * This file is world-readable and never goes invalid.
2599 2599           * It doesn't matter if we are in the middle of an exec().
2600 2600           */
2601 2601          p = pr_p_lock(pnp);
2602 2602          mutex_exit(&pr_pidlock);
2603 2603          if (p == NULL) {
2604 2604                  error = ENOENT;
2605 2605                  goto out;
2606 2606          }
2607 2607          ASSERT(p == pnp->pr_common->prc_proc);
2608 2608          if (pnp->pr_common->prc_thread == NULL) {
2609 2609                  prunlock(pnp);
2610 2610                  error = ENOENT;
2611 2611                  goto out;
2612 2612          }
2613 2613          if (uiop->uio_offset >= sizeof (prusage32_t)) {
2614 2614                  prunlock(pnp);
2615 2615                  error = 0;
2616 2616                  goto out;
2617 2617          }
2618 2618  
2619 2619          pup->pr_tstamp = gethrtime();
2620 2620          prgetusage(pnp->pr_common->prc_thread, pup);
2621 2621  
2622 2622          prunlock(pnp);
2623 2623  
2624 2624          prcvtusage32(pup, upup);
2625 2625  
2626 2626          error = pr_uioread(upup, sizeof (prusage32_t), uiop);
2627 2627  out:
2628 2628          kmem_free(pup, sizeof (*pup));
2629 2629          kmem_free(upup, sizeof (*upup));
2630 2630          return (error);
2631 2631  }
2632 2632  
2633 2633  static int
2634 2634  pr_read_spymaster_32(prnode_t *pnp, uio_t *uiop)
2635 2635  {
2636 2636          psinfo32_t psinfo;
2637 2637          int error;
2638 2638          klwp_t *lwp;
2639 2639  
2640 2640          ASSERT(pnp->pr_type == PR_SPYMASTER);
2641 2641  
2642 2642          if ((error = prlock(pnp, ZNO)) != 0)
2643 2643                  return (error);
2644 2644  
2645 2645          lwp = pnp->pr_common->prc_thread->t_lwp;
2646 2646  
2647 2647          if (lwp->lwp_spymaster == NULL) {
2648 2648                  prunlock(pnp);
2649 2649                  return (0);
2650 2650          }
2651 2651  
2652 2652          psinfo_kto32(lwp->lwp_spymaster, &psinfo);
2653 2653          prunlock(pnp);
2654 2654  
2655 2655          return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
2656 2656  }
2657 2657  
2658 2658  #if defined(__sparc)
2659 2659  static int
2660 2660  pr_read_gwindows_32(prnode_t *pnp, uio_t *uiop)
2661 2661  {
2662 2662          proc_t *p;
2663 2663          kthread_t *t;
2664 2664          gwindows32_t *gwp;
2665 2665          int error;
2666 2666          size_t size;
2667 2667  
2668 2668          ASSERT(pnp->pr_type == PR_GWINDOWS);
2669 2669  
2670 2670          gwp = kmem_zalloc(sizeof (gwindows32_t), KM_SLEEP);
2671 2671  
2672 2672          if ((error = prlock(pnp, ZNO)) != 0)
2673 2673                  goto out;
2674 2674  
2675 2675          p = pnp->pr_common->prc_proc;
2676 2676          t = pnp->pr_common->prc_thread;
2677 2677  
2678 2678          if (PROCESS_NOT_32BIT(p)) {
2679 2679                  prunlock(pnp);
2680 2680                  error = EOVERFLOW;
2681 2681                  goto out;
2682 2682          }
2683 2683  
2684 2684          /*
2685 2685           * Drop p->p_lock while touching the stack.
2686 2686           * The P_PR_LOCK flag prevents the lwp from
2687 2687           * disappearing while we do this.
2688 2688           */
2689 2689          mutex_exit(&p->p_lock);
2690 2690          if ((size = prnwindows(ttolwp(t))) != 0)
2691 2691                  size = sizeof (gwindows32_t) -
2692 2692                      (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow32);
2693 2693          if (uiop->uio_offset >= size) {
2694 2694                  mutex_enter(&p->p_lock);
2695 2695                  prunlock(pnp);
2696 2696                  goto out;
2697 2697          }
2698 2698          prgetwindows32(ttolwp(t), gwp);
2699 2699          mutex_enter(&p->p_lock);
2700 2700          prunlock(pnp);
2701 2701  
2702 2702          error = pr_uioread(gwp, size, uiop);
2703 2703  out:
2704 2704          kmem_free(gwp, sizeof (gwindows32_t));
2705 2705          return (error);
2706 2706  }
2707 2707  #endif  /* __sparc */
2708 2708  
2709 2709  #endif  /* _SYSCALL32_IMPL */
2710 2710  
2711 2711  /* ARGSUSED */
2712 2712  static int
2713 2713  prread(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2714 2714  {
2715 2715          prnode_t *pnp = VTOP(vp);
2716 2716  
2717 2717          ASSERT(pnp->pr_type < PR_NFILES);
2718 2718  
2719 2719  #ifdef _SYSCALL32_IMPL
2720 2720          /*
2721 2721           * What is read from the /proc files depends on the data
2722 2722           * model of the caller.  An LP64 process will see LP64
2723 2723           * data.  An ILP32 process will see ILP32 data.
2724 2724           */
2725 2725          if (curproc->p_model == DATAMODEL_LP64)
2726 2726                  return (pr_read_function[pnp->pr_type](pnp, uiop));
2727 2727          else
2728 2728                  return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2729 2729  #else
2730 2730          return (pr_read_function[pnp->pr_type](pnp, uiop));
2731 2731  #endif
2732 2732  }
2733 2733  
2734 2734  /*
2735 2735   * We make pr_write_psinfo_fname() somewhat simpler by asserting at compile
2736 2736   * time that PRFNSZ has the same definition as MAXCOMLEN.
2737 2737   */
2738 2738  #if PRFNSZ != MAXCOMLEN
2739 2739  #error PRFNSZ/MAXCOMLEN mismatch
2740 2740  #endif
2741 2741  
2742 2742  static int
2743 2743  pr_write_psinfo_fname(prnode_t *pnp, uio_t *uiop)
2744 2744  {
2745 2745          char fname[PRFNSZ];
2746 2746          int offset = offsetof(psinfo_t, pr_fname), error;
2747 2747  
2748 2748  #ifdef _SYSCALL32_IMPL
2749 2749          if (curproc->p_model != DATAMODEL_LP64)
2750 2750                  offset = offsetof(psinfo32_t, pr_fname);
2751 2751  #endif
2752 2752  
2753 2753          /*
2754 2754           * If this isn't a write to pr_fname (or if the size doesn't match
2755 2755           * PRFNSZ) return.
2756 2756           */
2757 2757          if (uiop->uio_offset != offset || uiop->uio_resid != PRFNSZ)
2758 2758                  return (0);
2759 2759  
2760 2760          if ((error = uiomove(fname, PRFNSZ, UIO_WRITE, uiop)) != 0)
2761 2761                  return (error);
2762 2762  
2763 2763          fname[PRFNSZ - 1] = '\0';
2764 2764  
2765 2765          if ((error = prlock(pnp, ZNO)) != 0)
2766 2766                  return (error);
2767 2767  
2768 2768          bcopy(fname, pnp->pr_common->prc_proc->p_user.u_comm, PRFNSZ);
2769 2769  
2770 2770          prunlock(pnp);
2771 2771  
2772 2772          return (0);
2773 2773  }
2774 2774  
2775 2775  /*
2776 2776   * We make pr_write_psinfo_psargs() somewhat simpler by asserting at compile
2777 2777   * time that PRARGSZ has the same definition as PSARGSZ.
2778 2778   */
2779 2779  #if PRARGSZ != PSARGSZ
2780 2780  #error PRARGSZ/PSARGSZ mismatch
2781 2781  #endif
2782 2782  
2783 2783  static int
2784 2784  pr_write_psinfo_psargs(prnode_t *pnp, uio_t *uiop)
2785 2785  {
2786 2786          char psargs[PRARGSZ];
2787 2787          int offset = offsetof(psinfo_t, pr_psargs), error;
2788 2788  
2789 2789  #ifdef _SYSCALL32_IMPL
2790 2790          if (curproc->p_model != DATAMODEL_LP64)
2791 2791                  offset = offsetof(psinfo32_t, pr_psargs);
2792 2792  #endif
2793 2793  
2794 2794          /*
2795 2795           * If this isn't a write to pr_psargs (or if the size doesn't match
2796 2796           * PRARGSZ) return.
2797 2797           */
2798 2798          if (uiop->uio_offset != offset || uiop->uio_resid != PRARGSZ)
2799 2799                  return (0);
2800 2800  
2801 2801          if ((error = uiomove(psargs, PRARGSZ, UIO_WRITE, uiop)) != 0)
2802 2802                  return (error);
2803 2803  
2804 2804          psargs[PRARGSZ - 1] = '\0';
2805 2805  
2806 2806          if ((error = prlock(pnp, ZNO)) != 0)
2807 2807                  return (error);
2808 2808  
2809 2809          bcopy(psargs, pnp->pr_common->prc_proc->p_user.u_psargs, PRARGSZ);
2810 2810  
2811 2811          prunlock(pnp);
2812 2812  
2813 2813          return (0);
2814 2814  }
2815 2815  
2816 2816  int
2817 2817  pr_write_psinfo(prnode_t *pnp, uio_t *uiop)
2818 2818  {
2819 2819          int error;
2820 2820  
2821 2821          if ((error = pr_write_psinfo_fname(pnp, uiop)) != 0)
2822 2822                  return (error);
2823 2823  
2824 2824          if ((error = pr_write_psinfo_psargs(pnp, uiop)) != 0)
2825 2825                  return (error);
2826 2826  
2827 2827          return (0);
2828 2828  }
2829 2829  
2830 2830  
2831 2831  /* ARGSUSED */
2832 2832  static int
2833 2833  prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2834 2834  {
2835 2835          prnode_t *pnp = VTOP(vp);
2836 2836          int old = 0;
2837 2837          int error;
2838 2838          ssize_t resid;
2839 2839  
2840 2840          ASSERT(pnp->pr_type < PR_NFILES);
2841 2841  
2842 2842          /*
2843 2843           * Only a handful of /proc files are writable, enumerate them here.
2844 2844           */
2845 2845          switch (pnp->pr_type) {
2846 2846          case PR_PIDDIR:         /* directory write()s: visceral revulsion. */
2847 2847                  ASSERT(pnp->pr_pidfile != NULL);
2848 2848                  /* use the underlying PR_PIDFILE to write the process */
2849 2849                  vp = pnp->pr_pidfile;
2850 2850                  pnp = VTOP(vp);
2851 2851                  ASSERT(pnp->pr_type == PR_PIDFILE);
2852 2852                  /* FALLTHROUGH */
2853 2853          case PR_PIDFILE:
2854 2854          case PR_LWPIDFILE:
2855 2855                  old = 1;
2856 2856                  /* FALLTHROUGH */
2857 2857          case PR_AS:
2858 2858                  if ((error = prlock(pnp, ZNO)) == 0) {
2859 2859                          proc_t *p = pnp->pr_common->prc_proc;
2860 2860                          struct as *as = p->p_as;
2861 2861  
2862 2862                          if ((p->p_flag & SSYS) || as == &kas) {
2863 2863                                  /*
2864 2864                                   * /proc I/O cannot be done to a system process.
2865 2865                                   */
2866 2866                                  error = EIO;
2867 2867  #ifdef _SYSCALL32_IMPL
2868 2868                          } else if (curproc->p_model == DATAMODEL_ILP32 &&
2869 2869                              PROCESS_NOT_32BIT(p)) {
2870 2870                                  error = EOVERFLOW;
2871 2871  #endif
2872 2872                          } else {
2873 2873                                  /*
2874 2874                                   * See comments above (pr_read_pidfile)
2875 2875                                   * about this locking dance.
2876 2876                                   */
2877 2877                                  mutex_exit(&p->p_lock);
2878 2878                                  error = prusrio(p, UIO_WRITE, uiop, old);
2879 2879                                  mutex_enter(&p->p_lock);
2880 2880                          }
2881 2881                          prunlock(pnp);
2882 2882                  }
2883 2883                  return (error);
2884 2884  
2885 2885          case PR_CTL:
2886 2886          case PR_LWPCTL:
2887 2887                  resid = uiop->uio_resid;
2888 2888                  /*
2889 2889                   * Perform the action on the control file
2890 2890                   * by passing curthreads credentials
2891 2891                   * and not target process's credentials.
2892 2892                   */
2893 2893  #ifdef _SYSCALL32_IMPL
2894 2894                  if (curproc->p_model == DATAMODEL_ILP32)
2895 2895                          error = prwritectl32(vp, uiop, CRED());
2896 2896                  else
2897 2897                          error = prwritectl(vp, uiop, CRED());
2898 2898  #else
2899 2899                  error = prwritectl(vp, uiop, CRED());
2900 2900  #endif
2901 2901                  /*
2902 2902                   * This hack makes sure that the EINTR is passed
2903 2903                   * all the way back to the caller's write() call.
2904 2904                   */
2905 2905                  if (error == EINTR)
2906 2906                          uiop->uio_resid = resid;
2907 2907                  return (error);
2908 2908  
2909 2909          case PR_PSINFO:
2910 2910                  return (pr_write_psinfo(pnp, uiop));
2911 2911  
2912 2912          default:
2913 2913                  return ((vp->v_type == VDIR)? EISDIR : EBADF);
2914 2914          }
2915 2915          /* NOTREACHED */
2916 2916  }
2917 2917  
2918 2918  static int
2919 2919  prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2920 2920          caller_context_t *ct)
2921 2921  {
2922 2922          prnode_t *pnp = VTOP(vp);
2923 2923          prnodetype_t type = pnp->pr_type;
2924 2924          prcommon_t *pcp;
2925 2925          proc_t *p;
2926 2926          struct as *as;
2927 2927          int error;
2928 2928          vnode_t *rvp;
2929 2929          timestruc_t now;
2930 2930          extern uint_t nproc;
2931 2931          int ngroups;
2932 2932          int nsig;
2933 2933  
2934 2934          /*
2935 2935           * This ugly bit of code allows us to keep both versions of this
2936 2936           * function from the same source.
2937 2937           */
2938 2938  #ifdef _LP64
2939 2939          int iam32bit = (curproc->p_model == DATAMODEL_ILP32);
2940 2940  #define PR_OBJSIZE(obj32, obj64)        \
2941 2941          (iam32bit ? sizeof (obj32) : sizeof (obj64))
2942 2942  #define PR_OBJSPAN(obj32, obj64)        \
2943 2943          (iam32bit ? LSPAN32(obj32) : LSPAN(obj64))
2944 2944  #else
2945 2945  #define PR_OBJSIZE(obj32, obj64)        \
2946 2946          (sizeof (obj64))
2947 2947  #define PR_OBJSPAN(obj32, obj64)        \
2948 2948          (LSPAN(obj64))
2949 2949  #endif
2950 2950  
2951 2951          /*
2952 2952           * Return all the attributes.  Should be refined
2953 2953           * so that it returns only those asked for.
2954 2954           * Most of this is complete fakery anyway.
2955 2955           */
2956 2956  
2957 2957          /*
2958 2958           * For files in the /proc/<pid>/object directory,
2959 2959           * return the attributes of the underlying object.
2960 2960           * For files in the /proc/<pid>/fd directory,
2961 2961           * return the attributes of the underlying file, but
2962 2962           * make it look inaccessible if it is not a regular file.
2963 2963           * Make directories look like symlinks.
2964 2964           */
2965 2965          switch (type) {
2966 2966          case PR_CURDIR:
2967 2967          case PR_ROOTDIR:
2968 2968                  if (!(flags & ATTR_REAL))
2969 2969                          break;
2970 2970                  /* restrict full knowledge of the attributes to owner or root */
2971 2971                  if ((error = praccess(vp, 0, 0, cr, ct)) != 0)
2972 2972                          return (error);
2973 2973                  /* FALLTHROUGH */
2974 2974          case PR_OBJECT:
2975 2975          case PR_FD:
2976 2976                  rvp = pnp->pr_realvp;
2977 2977                  error = VOP_GETATTR(rvp, vap, flags, cr, ct);
2978 2978                  if (error)
2979 2979                          return (error);
2980 2980                  if (type == PR_FD) {
2981 2981                          if (rvp->v_type != VREG && rvp->v_type != VDIR)
2982 2982                                  vap->va_mode = 0;
2983 2983                          else
2984 2984                                  vap->va_mode &= pnp->pr_mode;
2985 2985                  }
2986 2986                  if (type == PR_OBJECT)
2987 2987                          vap->va_mode &= 07555;
2988 2988                  if (rvp->v_type == VDIR && !(flags & ATTR_REAL)) {
2989 2989                          vap->va_type = VLNK;
2990 2990                          vap->va_size = 0;
2991 2991                          vap->va_nlink = 1;
2992 2992                  }
2993 2993                  return (0);
2994 2994          default:
2995 2995                  break;
2996 2996          }
2997 2997  
2998 2998          bzero(vap, sizeof (*vap));
2999 2999          /*
3000 3000           * Large Files: Internally proc now uses VPROC to indicate
3001 3001           * a proc file. Since we have been returning VREG through
3002 3002           * VOP_GETATTR() until now, we continue to do this so as
3003 3003           * not to break apps depending on this return value.
3004 3004           */
3005 3005          vap->va_type = (vp->v_type == VPROC) ? VREG : vp->v_type;
3006 3006          vap->va_mode = pnp->pr_mode;
3007 3007          vap->va_fsid = vp->v_vfsp->vfs_dev;
3008 3008          vap->va_blksize = DEV_BSIZE;
3009 3009          vap->va_rdev = 0;
3010 3010          vap->va_seq = 0;
3011 3011  
3012 3012          if (type == PR_PROCDIR) {
3013 3013                  vap->va_uid = 0;
3014 3014                  vap->va_gid = 0;
3015 3015                  vap->va_nlink = nproc + 2;
3016 3016                  vap->va_nodeid = (ino64_t)PRROOTINO;
3017 3017                  gethrestime(&now);
3018 3018                  vap->va_atime = vap->va_mtime = vap->va_ctime = now;
3019 3019                  vap->va_size = (v.v_proc + 2) * PRSDSIZE;
3020 3020                  vap->va_nblocks = btod(vap->va_size);
3021 3021                  return (0);
3022 3022          }
3023 3023  
3024 3024          /*
3025 3025           * /proc/<pid>/self is a symbolic link, and has no prcommon member
3026 3026           */
3027 3027          if (type == PR_SELF) {
3028 3028                  vap->va_uid = crgetruid(CRED());
3029 3029                  vap->va_gid = crgetrgid(CRED());
3030 3030                  vap->va_nodeid = (ino64_t)PR_SELF;
3031 3031                  gethrestime(&now);
3032 3032                  vap->va_atime = vap->va_mtime = vap->va_ctime = now;
3033 3033                  vap->va_nlink = 1;
3034 3034                  vap->va_type = VLNK;
3035 3035                  vap->va_size = 0;
3036 3036                  return (0);
3037 3037          }
3038 3038  
3039 3039          p = pr_p_lock(pnp);
3040 3040          mutex_exit(&pr_pidlock);
3041 3041          if (p == NULL)
3042 3042                  return (ENOENT);
3043 3043          pcp = pnp->pr_common;
3044 3044  
3045 3045          mutex_enter(&p->p_crlock);
3046 3046          vap->va_uid = crgetruid(p->p_cred);
3047 3047          vap->va_gid = crgetrgid(p->p_cred);
3048 3048          mutex_exit(&p->p_crlock);
3049 3049  
3050 3050          vap->va_nlink = 1;
3051 3051          vap->va_nodeid = pnp->pr_ino? pnp->pr_ino :
3052 3052              pmkino(pcp->prc_tslot, pcp->prc_slot, pnp->pr_type);
3053 3053          if ((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot != -1) {
3054 3054                  vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
3055 3055                      vap->va_ctime.tv_sec =
3056 3056                      p->p_lwpdir[pcp->prc_tslot].ld_entry->le_start;
3057 3057                  vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
3058 3058                      vap->va_ctime.tv_nsec = 0;
3059 3059          } else {
3060 3060                  user_t *up = PTOU(p);
3061 3061                  vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
3062 3062                      vap->va_ctime.tv_sec = up->u_start.tv_sec;
3063 3063                  vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
3064 3064                      vap->va_ctime.tv_nsec = up->u_start.tv_nsec;
3065 3065          }
3066 3066  
3067 3067          switch (type) {
3068 3068          case PR_PIDDIR:
3069 3069                  /* va_nlink: count 'lwp', 'object' and 'fd' directory links */
3070 3070                  vap->va_nlink = 5;
3071 3071                  vap->va_size = sizeof (piddir);
3072 3072                  break;
3073 3073          case PR_OBJECTDIR:
3074 3074                  if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3075 3075                          vap->va_size = 2 * PRSDSIZE;
3076 3076                  else {
3077 3077                          mutex_exit(&p->p_lock);
3078 3078                          AS_LOCK_ENTER(as, RW_WRITER);
3079 3079                          if (as->a_updatedir)
3080 3080                                  rebuild_objdir(as);
3081 3081                          vap->va_size = (as->a_sizedir + 2) * PRSDSIZE;
3082 3082                          AS_LOCK_EXIT(as);
3083 3083                          mutex_enter(&p->p_lock);
3084 3084                  }
3085 3085                  vap->va_nlink = 2;
3086 3086                  break;
3087 3087          case PR_PATHDIR:
3088 3088                  if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3089 3089                          vap->va_size = (P_FINFO(p)->fi_nfiles + 4) * PRSDSIZE;
3090 3090                  else {
3091 3091                          mutex_exit(&p->p_lock);
3092 3092                          AS_LOCK_ENTER(as, RW_WRITER);
3093 3093                          if (as->a_updatedir)
3094 3094                                  rebuild_objdir(as);
3095 3095                          vap->va_size = (as->a_sizedir + 4 +
3096 3096                              P_FINFO(p)->fi_nfiles) * PRSDSIZE;
3097 3097                          AS_LOCK_EXIT(as);
3098 3098                          mutex_enter(&p->p_lock);
3099 3099                  }
3100 3100                  vap->va_nlink = 2;
3101 3101                  break;
3102 3102          case PR_PATH:
3103 3103          case PR_CURDIR:
3104 3104          case PR_ROOTDIR:
3105 3105          case PR_CT:
3106 3106                  vap->va_type = VLNK;
3107 3107                  vap->va_size = 0;
3108 3108                  break;
3109 3109          case PR_FDDIR:
3110 3110                  vap->va_nlink = 2;
3111 3111                  vap->va_size = (P_FINFO(p)->fi_nfiles + 2) * PRSDSIZE;
3112 3112                  break;
3113 3113          case PR_LWPDIR:
3114 3114                  /*
3115 3115                   * va_nlink: count each lwp as a directory link.
3116 3116                   * va_size: size of p_lwpdir + 2
3117 3117                   */
3118 3118                  vap->va_nlink = p->p_lwpcnt + p->p_zombcnt + 2;
3119 3119                  vap->va_size = (p->p_lwpdir_sz + 2) * PRSDSIZE;
3120 3120                  break;
3121 3121          case PR_LWPIDDIR:
3122 3122                  vap->va_nlink = 2;
3123 3123                  vap->va_size = sizeof (lwpiddir);
3124 3124                  break;
3125 3125          case PR_CTDIR:
3126 3126                  vap->va_nlink = 2;
3127 3127                  vap->va_size = (avl_numnodes(&p->p_ct_held) + 2) * PRSDSIZE;
3128 3128                  break;
3129 3129          case PR_TMPLDIR:
3130 3130                  vap->va_nlink = 2;
3131 3131                  vap->va_size = (ct_ntypes + 2) * PRSDSIZE;
3132 3132                  break;
3133 3133          case PR_AS:
3134 3134          case PR_PIDFILE:
3135 3135          case PR_LWPIDFILE:
3136 3136                  if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3137 3137                          vap->va_size = 0;
3138 3138                  else
3139 3139                          vap->va_size = as->a_resvsize;
3140 3140                  break;
3141 3141          case PR_STATUS:
3142 3142                  vap->va_size = PR_OBJSIZE(pstatus32_t, pstatus_t);
3143 3143                  break;
3144 3144          case PR_LSTATUS:
3145 3145                  vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3146 3146                      p->p_lwpcnt * PR_OBJSPAN(lwpstatus32_t, lwpstatus_t);
3147 3147                  break;
3148 3148          case PR_PSINFO:
3149 3149                  vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3150 3150                  break;
3151 3151          case PR_LPSINFO:
3152 3152                  vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3153 3153                      (p->p_lwpcnt + p->p_zombcnt) *
3154 3154                      PR_OBJSPAN(lwpsinfo32_t, lwpsinfo_t);
3155 3155                  break;
3156 3156          case PR_MAP:
3157 3157          case PR_RMAP:
3158 3158          case PR_XMAP:
3159 3159                  if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3160 3160                          vap->va_size = 0;
3161 3161                  else {
3162 3162                          mutex_exit(&p->p_lock);
3163 3163                          AS_LOCK_ENTER(as, RW_WRITER);
3164 3164                          if (type == PR_MAP)
3165 3165                                  vap->va_mtime = as->a_updatetime;
3166 3166                          if (type == PR_XMAP)
3167 3167                                  vap->va_size = prnsegs(as, 0) *
3168 3168                                      PR_OBJSIZE(prxmap32_t, prxmap_t);
3169 3169                          else
3170 3170                                  vap->va_size = prnsegs(as, type == PR_RMAP) *
3171 3171                                      PR_OBJSIZE(prmap32_t, prmap_t);
3172 3172                          AS_LOCK_EXIT(as);
3173 3173                          mutex_enter(&p->p_lock);
3174 3174                  }
3175 3175                  break;
3176 3176          case PR_CRED:
3177 3177                  mutex_enter(&p->p_crlock);
3178 3178                  vap->va_size = sizeof (prcred_t);
3179 3179                  ngroups = crgetngroups(p->p_cred);
3180 3180                  if (ngroups > 1)
3181 3181                          vap->va_size += (ngroups - 1) * sizeof (gid_t);
3182 3182                  mutex_exit(&p->p_crlock);
3183 3183                  break;
3184 3184          case PR_PRIV:
3185 3185                  vap->va_size = prgetprivsize();
3186 3186                  break;
3187 3187          case PR_SIGACT:
3188 3188                  nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
3189 3189                  vap->va_size = (nsig-1) *
3190 3190                      PR_OBJSIZE(struct sigaction32, struct sigaction);
3191 3191                  break;
3192 3192          case PR_AUXV:
3193 3193                  vap->va_size = __KERN_NAUXV_IMPL * PR_OBJSIZE(auxv32_t, auxv_t);
3194 3194                  break;
3195 3195          case PR_ARGV:
3196 3196                  if ((p->p_flag & SSYS) || p->p_as == &kas) {
3197 3197                          vap->va_size = PSARGSZ;
3198 3198                  } else {
3199 3199                          vap->va_size = prmaxargvlen;
3200 3200                  }
3201 3201                  break;
3202 3202  #if defined(__x86)
3203 3203          case PR_LDT:
3204 3204                  mutex_exit(&p->p_lock);
3205 3205                  mutex_enter(&p->p_ldtlock);
3206 3206                  vap->va_size = prnldt(p) * sizeof (struct ssd);
3207 3207                  mutex_exit(&p->p_ldtlock);
3208 3208                  mutex_enter(&p->p_lock);
3209 3209                  break;
3210 3210  #endif
3211 3211          case PR_USAGE:
3212 3212                  vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3213 3213                  break;
3214 3214          case PR_LUSAGE:
3215 3215                  vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3216 3216                      (p->p_lwpcnt + 1) * PR_OBJSPAN(prusage32_t, prusage_t);
3217 3217                  break;
3218 3218          case PR_PAGEDATA:
3219 3219                  if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3220 3220                          vap->va_size = 0;
3221 3221                  else {
3222 3222                          /*
3223 3223                           * We can drop p->p_lock before grabbing the
3224 3224                           * address space lock because p->p_as will not
3225 3225                           * change while the process is marked P_PR_LOCK.
3226 3226                           */
3227 3227                          mutex_exit(&p->p_lock);
3228 3228                          AS_LOCK_ENTER(as, RW_WRITER);
3229 3229  #ifdef _LP64
3230 3230                          vap->va_size = iam32bit?
3231 3231                              prpdsize32(as) : prpdsize(as);
3232 3232  #else
3233 3233                          vap->va_size = prpdsize(as);
3234 3234  #endif
3235 3235                          AS_LOCK_EXIT(as);
3236 3236                          mutex_enter(&p->p_lock);
3237 3237                  }
3238 3238                  break;
3239 3239          case PR_OPAGEDATA:
3240 3240                  if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3241 3241                          vap->va_size = 0;
3242 3242                  else {
3243 3243                          mutex_exit(&p->p_lock);
3244 3244                          AS_LOCK_ENTER(as, RW_WRITER);
3245 3245  #ifdef _LP64
3246 3246                          vap->va_size = iam32bit?
3247 3247                              oprpdsize32(as) : oprpdsize(as);
3248 3248  #else
3249 3249                          vap->va_size = oprpdsize(as);
3250 3250  #endif
3251 3251                          AS_LOCK_EXIT(as);
3252 3252                          mutex_enter(&p->p_lock);
3253 3253                  }
3254 3254                  break;
3255 3255          case PR_WATCH:
3256 3256                  vap->va_size = avl_numnodes(&p->p_warea) *
3257 3257                      PR_OBJSIZE(prwatch32_t, prwatch_t);
3258 3258                  break;
3259 3259          case PR_LWPSTATUS:
3260 3260                  vap->va_size = PR_OBJSIZE(lwpstatus32_t, lwpstatus_t);
3261 3261                  break;
3262 3262          case PR_LWPSINFO:
3263 3263                  vap->va_size = PR_OBJSIZE(lwpsinfo32_t, lwpsinfo_t);
3264 3264                  break;
3265 3265          case PR_LWPUSAGE:
3266 3266                  vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3267 3267                  break;
3268 3268          case PR_XREGS:
3269 3269                  if (prhasx(p))
3270 3270                          vap->va_size = prgetprxregsize(p);
3271 3271                  else
3272 3272                          vap->va_size = 0;
3273 3273                  break;
3274 3274          case PR_SPYMASTER:
3275 3275                  if (pnp->pr_common->prc_thread->t_lwp->lwp_spymaster != NULL) {
3276 3276                          vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3277 3277                  } else {
3278 3278                          vap->va_size = 0;
3279 3279                  }
3280 3280                  break;
3281 3281  #if defined(__sparc)
3282 3282          case PR_GWINDOWS:
3283 3283          {
3284 3284                  kthread_t *t;
3285 3285                  int n;
3286 3286  
3287 3287                  /*
3288 3288                   * If there is no lwp then just make the size zero.
3289 3289                   * This can happen if the lwp exits between the VOP_LOOKUP()
3290 3290                   * of the /proc/<pid>/lwp/<lwpid>/gwindows file and the
3291 3291                   * VOP_GETATTR() of the resulting vnode.
3292 3292                   */
3293 3293                  if ((t = pcp->prc_thread) == NULL) {
3294 3294                          vap->va_size = 0;
3295 3295                          break;
3296 3296                  }
3297 3297                  /*
3298 3298                   * Drop p->p_lock while touching the stack.
3299 3299                   * The P_PR_LOCK flag prevents the lwp from
3300 3300                   * disappearing while we do this.
3301 3301                   */
3302 3302                  mutex_exit(&p->p_lock);
3303 3303                  if ((n = prnwindows(ttolwp(t))) == 0)
3304 3304                          vap->va_size = 0;
3305 3305                  else
3306 3306                          vap->va_size = PR_OBJSIZE(gwindows32_t, gwindows_t) -
3307 3307                              (SPARC_MAXREGWINDOW - n) *
3308 3308                              PR_OBJSIZE(struct rwindow32, struct rwindow);
3309 3309                  mutex_enter(&p->p_lock);
3310 3310                  break;
3311 3311          }
3312 3312          case PR_ASRS:
3313 3313  #ifdef _LP64
3314 3314                  if (p->p_model == DATAMODEL_LP64)
3315 3315                          vap->va_size = sizeof (asrset_t);
3316 3316                  else
3317 3317  #endif
3318 3318                          vap->va_size = 0;
3319 3319                  break;
3320 3320  #endif
3321 3321          case PR_CTL:
3322 3322          case PR_LWPCTL:
3323 3323          default:
3324 3324                  vap->va_size = 0;
3325 3325                  break;
3326 3326          }
3327 3327  
3328 3328          prunlock(pnp);
3329 3329          vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size);
3330 3330          return (0);
3331 3331  }
3332 3332  
3333 3333  static int
3334 3334  praccess(vnode_t *vp, int mode, int flags, cred_t *cr, caller_context_t *ct)
3335 3335  {
3336 3336          prnode_t *pnp = VTOP(vp);
3337 3337          prnodetype_t type = pnp->pr_type;
3338 3338          int vmode;
3339 3339          vtype_t vtype;
3340 3340          proc_t *p;
3341 3341          int error = 0;
3342 3342          vnode_t *rvp;
3343 3343          vnode_t *xvp;
3344 3344  
3345 3345          if ((mode & VWRITE) && vn_is_readonly(vp))
3346 3346                  return (EROFS);
3347 3347  
3348 3348          switch (type) {
3349 3349          case PR_PROCDIR:
3350 3350                  break;
3351 3351  
3352 3352          case PR_OBJECT:
3353 3353          case PR_FD:
3354 3354                  /*
3355 3355                   * Disallow write access to the underlying objects.
3356 3356                   * Disallow access to underlying non-regular-file fds.
3357 3357                   * Disallow access to fds with other than existing open modes.
3358 3358                   */
3359 3359                  rvp = pnp->pr_realvp;
3360 3360                  vtype = rvp->v_type;
3361 3361                  vmode = pnp->pr_mode;
3362 3362                  if ((type == PR_OBJECT && (mode & VWRITE)) ||
3363 3363                      (type == PR_FD && vtype != VREG && vtype != VDIR) ||
3364 3364                      (type == PR_FD && (vmode & mode) != mode &&
3365 3365                      secpolicy_proc_access(cr) != 0))
3366 3366                          return (EACCES);
3367 3367                  return (VOP_ACCESS(rvp, mode, flags, cr, ct));
3368 3368  
3369 3369          case PR_PSINFO:         /* these files can be read by anyone */
3370 3370          case PR_LPSINFO:
3371 3371          case PR_LWPSINFO:
3372 3372          case PR_LWPDIR:
3373 3373          case PR_LWPIDDIR:
3374 3374          case PR_USAGE:
3375 3375          case PR_LUSAGE:
3376 3376          case PR_LWPUSAGE:
3377 3377          case PR_ARGV:
3378 3378                  p = pr_p_lock(pnp);
3379 3379                  mutex_exit(&pr_pidlock);
3380 3380                  if (p == NULL)
3381 3381                          return (ENOENT);
3382 3382                  prunlock(pnp);
3383 3383                  break;
3384 3384  
3385 3385          default:
3386 3386                  /*
3387 3387                   * Except for the world-readable files above,
3388 3388                   * only /proc/pid exists if the process is a zombie.
3389 3389                   */
3390 3390                  if ((error = prlock(pnp,
3391 3391                      (type == PR_PIDDIR)? ZYES : ZNO)) != 0)
3392 3392                          return (error);
3393 3393                  p = pnp->pr_common->prc_proc;
3394 3394                  if (p != curproc)
3395 3395                          error = priv_proc_cred_perm(cr, p, NULL, mode);
3396 3396  
3397 3397                  if (error != 0 || p == curproc || (p->p_flag & SSYS) ||
3398 3398                      p->p_as == &kas || (xvp = p->p_exec) == NULL) {
3399 3399                          prunlock(pnp);
3400 3400                  } else {
3401 3401                          /*
3402 3402                           * Determine if the process's executable is readable.
3403 3403                           * We have to drop p->p_lock before the secpolicy
3404 3404                           * and VOP operation.
3405 3405                           */
3406 3406                          VN_HOLD(xvp);
3407 3407                          prunlock(pnp);
3408 3408                          if (secpolicy_proc_access(cr) != 0)
3409 3409                                  error = VOP_ACCESS(xvp, VREAD, 0, cr, ct);
3410 3410                          VN_RELE(xvp);
3411 3411                  }
3412 3412                  if (error)
3413 3413                          return (error);
3414 3414                  break;
3415 3415          }
3416 3416  
3417 3417          if (type == PR_CURDIR || type == PR_ROOTDIR) {
3418 3418                  /*
3419 3419                   * Final access check on the underlying directory vnode.
3420 3420                   */
3421 3421                  return (VOP_ACCESS(pnp->pr_realvp, mode, flags, cr, ct));
3422 3422          }
3423 3423  
3424 3424          /*
3425 3425           * Visceral revulsion:  For compatibility with old /proc,
3426 3426           * allow the /proc/<pid> directory to be opened for writing.
3427 3427           */
3428 3428          vmode = pnp->pr_mode;
3429 3429          if (type == PR_PIDDIR)
3430 3430                  vmode |= VWRITE;
3431 3431          if ((vmode & mode) != mode)
3432 3432                  error = secpolicy_proc_access(cr);
3433 3433          return (error);
3434 3434  }
3435 3435  
3436 3436  /*
3437 3437   * Array of lookup functions, indexed by /proc file type.
3438 3438   */
3439 3439  static vnode_t *pr_lookup_notdir(), *pr_lookup_procdir(), *pr_lookup_piddir(),
3440 3440          *pr_lookup_objectdir(), *pr_lookup_lwpdir(), *pr_lookup_lwpiddir(),
3441 3441          *pr_lookup_fddir(), *pr_lookup_pathdir(), *pr_lookup_tmpldir(),
3442 3442          *pr_lookup_ctdir();
3443 3443  
3444 3444  static vnode_t *(*pr_lookup_function[PR_NFILES])() = {
3445 3445          pr_lookup_procdir,      /* /proc                                */
3446 3446          pr_lookup_notdir,       /* /proc/self                           */
3447 3447          pr_lookup_piddir,       /* /proc/<pid>                          */
3448 3448          pr_lookup_notdir,       /* /proc/<pid>/as                       */
3449 3449          pr_lookup_notdir,       /* /proc/<pid>/ctl                      */
3450 3450          pr_lookup_notdir,       /* /proc/<pid>/status                   */
3451 3451          pr_lookup_notdir,       /* /proc/<pid>/lstatus                  */
3452 3452          pr_lookup_notdir,       /* /proc/<pid>/psinfo                   */
3453 3453          pr_lookup_notdir,       /* /proc/<pid>/lpsinfo                  */
3454 3454          pr_lookup_notdir,       /* /proc/<pid>/map                      */
3455 3455          pr_lookup_notdir,       /* /proc/<pid>/rmap                     */
3456 3456          pr_lookup_notdir,       /* /proc/<pid>/xmap                     */
3457 3457          pr_lookup_notdir,       /* /proc/<pid>/cred                     */
3458 3458          pr_lookup_notdir,       /* /proc/<pid>/sigact                   */
3459 3459          pr_lookup_notdir,       /* /proc/<pid>/auxv                     */
3460 3460  #if defined(__x86)
3461 3461          pr_lookup_notdir,       /* /proc/<pid>/ldt                      */
3462 3462  #endif
3463 3463          pr_lookup_notdir,       /* /proc/<pid>/argv                     */
3464 3464          pr_lookup_notdir,       /* /proc/<pid>/usage                    */
3465 3465          pr_lookup_notdir,       /* /proc/<pid>/lusage                   */
3466 3466          pr_lookup_notdir,       /* /proc/<pid>/pagedata                 */
3467 3467          pr_lookup_notdir,       /* /proc/<pid>/watch                    */
3468 3468          pr_lookup_notdir,       /* /proc/<pid>/cwd                      */
3469 3469          pr_lookup_notdir,       /* /proc/<pid>/root                     */
3470 3470          pr_lookup_fddir,        /* /proc/<pid>/fd                       */
3471 3471          pr_lookup_notdir,       /* /proc/<pid>/fd/nn                    */
3472 3472          pr_lookup_objectdir,    /* /proc/<pid>/object                   */
3473 3473          pr_lookup_notdir,       /* /proc/<pid>/object/xxx               */
3474 3474          pr_lookup_lwpdir,       /* /proc/<pid>/lwp                      */
3475 3475          pr_lookup_lwpiddir,     /* /proc/<pid>/lwp/<lwpid>              */
3476 3476          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpctl       */
3477 3477          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpstatus    */
3478 3478          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo     */
3479 3479          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpusage     */
3480 3480          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/xregs        */
3481 3481          pr_lookup_tmpldir,      /* /proc/<pid>/lwp/<lwpid>/templates    */
3482 3482          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3483 3483          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/spymaster    */
3484 3484  #if defined(__sparc)
3485 3485          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/gwindows     */
3486 3486          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/asrs         */
3487 3487  #endif
3488 3488          pr_lookup_notdir,       /* /proc/<pid>/priv                     */
3489 3489          pr_lookup_pathdir,      /* /proc/<pid>/path                     */
3490 3490          pr_lookup_notdir,       /* /proc/<pid>/path/xxx                 */
3491 3491          pr_lookup_ctdir,        /* /proc/<pid>/contracts                */
3492 3492          pr_lookup_notdir,       /* /proc/<pid>/contracts/<ctid>         */
3493 3493          pr_lookup_notdir,       /* old process file                     */
3494 3494          pr_lookup_notdir,       /* old lwp file                         */
3495 3495          pr_lookup_notdir,       /* old pagedata file                    */
3496 3496  };
3497 3497  
3498 3498  static int
3499 3499  prlookup(vnode_t *dp, char *comp, vnode_t **vpp, pathname_t *pathp,
3500 3500          int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
3501 3501          int *direntflags, pathname_t *realpnp)
3502 3502  {
3503 3503          prnode_t *pnp = VTOP(dp);
3504 3504          prnodetype_t type = pnp->pr_type;
3505 3505          int error;
3506 3506  
3507 3507          ASSERT(dp->v_type == VDIR);
3508 3508          ASSERT(type < PR_NFILES);
3509 3509  
3510 3510          if (type != PR_PROCDIR && strcmp(comp, "..") == 0) {
3511 3511                  VN_HOLD(pnp->pr_parent);
3512 3512                  *vpp = pnp->pr_parent;
3513 3513                  return (0);
3514 3514          }
3515 3515  
3516 3516          if (*comp == '\0' ||
3517 3517              strcmp(comp, ".") == 0 || strcmp(comp, "..") == 0) {
3518 3518                  VN_HOLD(dp);
3519 3519                  *vpp = dp;
3520 3520                  return (0);
3521 3521          }
3522 3522  
3523 3523          switch (type) {
3524 3524          case PR_CURDIR:
3525 3525          case PR_ROOTDIR:
3526 3526                  /* restrict lookup permission to owner or root */
3527 3527                  if ((error = praccess(dp, VEXEC, 0, cr, ct)) != 0)
3528 3528                          return (error);
3529 3529                  /* FALLTHROUGH */
3530 3530          case PR_FD:
3531 3531                  dp = pnp->pr_realvp;
3532 3532                  return (VOP_LOOKUP(dp, comp, vpp, pathp, flags, rdir, cr, ct,
3533 3533                      direntflags, realpnp));
3534 3534          default:
3535 3535                  break;
3536 3536          }
3537 3537  
3538 3538          if ((type == PR_OBJECTDIR || type == PR_FDDIR || type == PR_PATHDIR) &&
3539 3539              (error = praccess(dp, VEXEC, 0, cr, ct)) != 0)
3540 3540                  return (error);
3541 3541  
3542 3542          /* XXX - Do we need to pass ct, direntflags, or realpnp? */
3543 3543          *vpp = (pr_lookup_function[type](dp, comp));
3544 3544  
3545 3545          return ((*vpp == NULL) ? ENOENT : 0);
3546 3546  }
3547 3547  
3548 3548  /* ARGSUSED */
3549 3549  static int
3550 3550  prcreate(vnode_t *dp, char *comp, vattr_t *vap, vcexcl_t excl,
3551 3551          int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct,
3552 3552          vsecattr_t *vsecp)
3553 3553  {
3554 3554          int error;
3555 3555  
3556 3556          if ((error = prlookup(dp, comp, vpp, NULL, 0, NULL, cr,
3557 3557              ct, NULL, NULL)) != 0) {
3558 3558                  if (error == ENOENT)    /* can't O_CREAT nonexistent files */
3559 3559                          error = EACCES;         /* unwriteable directories */
3560 3560          } else {
3561 3561                  if (excl == EXCL)                       /* O_EXCL */
3562 3562                          error = EEXIST;
3563 3563                  else if (vap->va_mask & AT_SIZE) {      /* O_TRUNC */
3564 3564                          vnode_t *vp = *vpp;
3565 3565                          uint_t mask;
3566 3566  
3567 3567                          if (vp->v_type == VDIR)
3568 3568                                  error = EISDIR;
3569 3569                          else if (vp->v_type != VPROC ||
3570 3570                              VTOP(vp)->pr_type != PR_FD)
3571 3571                                  error = EACCES;
3572 3572                          else {          /* /proc/<pid>/fd/<n> */
3573 3573                                  vp = VTOP(vp)->pr_realvp;
3574 3574                                  mask = vap->va_mask;
3575 3575                                  vap->va_mask = AT_SIZE;
3576 3576                                  error = VOP_SETATTR(vp, vap, 0, cr, ct);
3577 3577                                  vap->va_mask = mask;
3578 3578                          }
3579 3579                  }
3580 3580                  if (error) {
3581 3581                          VN_RELE(*vpp);
3582 3582                          *vpp = NULL;
3583 3583                  }
3584 3584          }
3585 3585          return (error);
3586 3586  }
3587 3587  
3588 3588  /* ARGSUSED */
3589 3589  static vnode_t *
3590 3590  pr_lookup_notdir(vnode_t *dp, char *comp)
3591 3591  {
3592 3592          return (NULL);
3593 3593  }
3594 3594  
3595 3595  /*
3596 3596   * Find or construct a process vnode for the given pid.
3597 3597   */
3598 3598  static vnode_t *
3599 3599  pr_lookup_procdir(vnode_t *dp, char *comp)
3600 3600  {
3601 3601          pid_t pid;
3602 3602          prnode_t *pnp;
3603 3603          prcommon_t *pcp;
3604 3604          vnode_t *vp;
3605 3605          proc_t *p;
3606 3606          int c;
3607 3607  
3608 3608          ASSERT(VTOP(dp)->pr_type == PR_PROCDIR);
3609 3609  
3610 3610          if (strcmp(comp, "self") == 0) {
3611 3611                  pnp = prgetnode(dp, PR_SELF);
3612 3612                  return (PTOV(pnp));
3613 3613          } else {
3614 3614                  pid = 0;
3615 3615                  while ((c = *comp++) != '\0') {
3616 3616                          if (c < '0' || c > '9')
3617 3617                                  return (NULL);
3618 3618                          pid = 10*pid + c - '0';
3619 3619                          if (pid > maxpid)
3620 3620                                  return (NULL);
3621 3621                  }
3622 3622          }
3623 3623  
3624 3624          pnp = prgetnode(dp, PR_PIDDIR);
3625 3625  
3626 3626          mutex_enter(&pidlock);
3627 3627          if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) {
3628 3628                  mutex_exit(&pidlock);
3629 3629                  prfreenode(pnp);
3630 3630                  return (NULL);
3631 3631          }
3632 3632          ASSERT(p->p_stat != 0);
3633 3633  
3634 3634          /* NOTE: we're holding pidlock across the policy call. */
3635 3635          if (secpolicy_basic_procinfo(CRED(), p, curproc) != 0) {
3636 3636                  mutex_exit(&pidlock);
3637 3637                  prfreenode(pnp);
3638 3638                  return (NULL);
3639 3639          }
3640 3640  
3641 3641          mutex_enter(&p->p_lock);
3642 3642          mutex_exit(&pidlock);
3643 3643  
3644 3644          /*
3645 3645           * If a process vnode already exists and it is not invalid
3646 3646           * and it was created by the current process and it belongs
3647 3647           * to the same /proc mount point as our parent vnode, then
3648 3648           * just use it and discard the newly-allocated prnode.
3649 3649           */
3650 3650          for (vp = p->p_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3651 3651                  if (!(VTOP(VTOP(vp)->pr_pidfile)->pr_flags & PR_INVAL) &&
3652 3652                      VTOP(vp)->pr_owner == curproc &&
3653 3653                      vp->v_vfsp == dp->v_vfsp) {
3654 3654                          ASSERT(!(VTOP(vp)->pr_flags & PR_INVAL));
3655 3655                          VN_HOLD(vp);
3656 3656                          prfreenode(pnp);
3657 3657                          mutex_exit(&p->p_lock);
3658 3658                          return (vp);
3659 3659                  }
3660 3660          }
3661 3661          pnp->pr_owner = curproc;
3662 3662  
3663 3663          /*
3664 3664           * prgetnode() initialized most of the prnode.
3665 3665           * Finish the job.
3666 3666           */
3667 3667          pcp = pnp->pr_common;   /* the newly-allocated prcommon struct */
3668 3668          if ((vp = p->p_trace) != NULL) {
3669 3669                  /* discard the new prcommon and use the existing prcommon */
3670 3670                  prfreecommon(pcp);
3671 3671                  pcp = VTOP(vp)->pr_common;
3672 3672                  mutex_enter(&pcp->prc_mutex);
3673 3673                  ASSERT(pcp->prc_refcnt > 0);
3674 3674                  pcp->prc_refcnt++;
3675 3675                  mutex_exit(&pcp->prc_mutex);
3676 3676                  pnp->pr_common = pcp;
3677 3677          } else {
3678 3678                  /* initialize the new prcommon struct */
3679 3679                  if ((p->p_flag & SSYS) || p->p_as == &kas)
3680 3680                          pcp->prc_flags |= PRC_SYS;
3681 3681                  if (p->p_stat == SZOMB)
3682 3682                          pcp->prc_flags |= PRC_DESTROY;
3683 3683                  pcp->prc_proc = p;
3684 3684                  pcp->prc_datamodel = p->p_model;
3685 3685                  pcp->prc_pid = p->p_pid;
3686 3686                  pcp->prc_slot = p->p_slot;
3687 3687          }
3688 3688          pnp->pr_pcommon = pcp;
3689 3689          pnp->pr_parent = dp;
3690 3690          VN_HOLD(dp);
3691 3691          /*
3692 3692           * Link in the old, invalid directory vnode so we
3693 3693           * can later determine the last close of the file.
3694 3694           */
3695 3695          pnp->pr_next = p->p_trace;
3696 3696          p->p_trace = dp = PTOV(pnp);
3697 3697  
3698 3698          /*
3699 3699           * Kludge for old /proc: initialize the PR_PIDFILE as well.
3700 3700           */
3701 3701          vp = pnp->pr_pidfile;
3702 3702          pnp = VTOP(vp);
3703 3703          pnp->pr_ino = ptoi(pcp->prc_pid);
3704 3704          pnp->pr_common = pcp;
3705 3705          pnp->pr_pcommon = pcp;
3706 3706          pnp->pr_parent = dp;
3707 3707          pnp->pr_next = p->p_plist;
3708 3708          p->p_plist = vp;
3709 3709  
3710 3710          mutex_exit(&p->p_lock);
3711 3711          return (dp);
3712 3712  }
3713 3713  
3714 3714  static vnode_t *
3715 3715  pr_lookup_piddir(vnode_t *dp, char *comp)
3716 3716  {
3717 3717          prnode_t *dpnp = VTOP(dp);
3718 3718          vnode_t *vp;
3719 3719          prnode_t *pnp;
3720 3720          proc_t *p;
3721 3721          user_t *up;
3722 3722          prdirent_t *dirp;
3723 3723          int i;
3724 3724          enum prnodetype type;
3725 3725  
3726 3726          ASSERT(dpnp->pr_type == PR_PIDDIR);
3727 3727  
3728 3728          for (i = 0; i < NPIDDIRFILES; i++) {
3729 3729                  /* Skip "." and ".." */
3730 3730                  dirp = &piddir[i+2];
3731 3731                  if (strcmp(comp, dirp->d_name) == 0)
3732 3732                          break;
3733 3733          }
3734 3734  
3735 3735          if (i >= NPIDDIRFILES)
3736 3736                  return (NULL);
3737 3737  
3738 3738          type = (int)dirp->d_ino;
3739 3739          pnp = prgetnode(dp, type);
3740 3740  
3741 3741          p = pr_p_lock(dpnp);
3742 3742          mutex_exit(&pr_pidlock);
3743 3743          if (p == NULL) {
3744 3744                  prfreenode(pnp);
3745 3745                  return (NULL);
3746 3746          }
3747 3747          if (dpnp->pr_pcommon->prc_flags & PRC_DESTROY) {
3748 3748                  switch (type) {
3749 3749                  case PR_PSINFO:
3750 3750                  case PR_USAGE:
3751 3751                          break;
3752 3752                  default:
3753 3753                          prunlock(dpnp);
3754 3754                          prfreenode(pnp);
3755 3755                          return (NULL);
3756 3756                  }
3757 3757          }
3758 3758  
3759 3759          switch (type) {
3760 3760          case PR_CURDIR:
3761 3761          case PR_ROOTDIR:
3762 3762                  up = PTOU(p);
3763 3763                  vp = (type == PR_CURDIR)? up->u_cdir :
3764 3764                      (up->u_rdir? up->u_rdir : rootdir);
3765 3765  
3766 3766                  if (vp == NULL) {       /* can't happen? */
3767 3767                          prunlock(dpnp);
3768 3768                          prfreenode(pnp);
3769 3769                          return (NULL);
3770 3770                  }
3771 3771                  /*
3772 3772                   * Fill in the prnode so future references will
3773 3773                   * be able to find the underlying object's vnode.
3774 3774                   */
3775 3775                  VN_HOLD(vp);
3776 3776                  pnp->pr_realvp = vp;
3777 3777                  break;
3778 3778          default:
3779 3779                  break;
3780 3780          }
3781 3781  
3782 3782          mutex_enter(&dpnp->pr_mutex);
3783 3783  
3784 3784          if ((vp = dpnp->pr_files[i]) != NULL &&
3785 3785              !(VTOP(vp)->pr_flags & PR_INVAL)) {
3786 3786                  VN_HOLD(vp);
3787 3787                  mutex_exit(&dpnp->pr_mutex);
3788 3788                  prunlock(dpnp);
3789 3789                  prfreenode(pnp);
3790 3790                  return (vp);
3791 3791          }
3792 3792  
3793 3793          /*
3794 3794           * prgetnode() initialized most of the prnode.
3795 3795           * Finish the job.
3796 3796           */
3797 3797          pnp->pr_common = dpnp->pr_common;
3798 3798          pnp->pr_pcommon = dpnp->pr_pcommon;
3799 3799          pnp->pr_parent = dp;
3800 3800          VN_HOLD(dp);
3801 3801          pnp->pr_index = i;
3802 3802  
3803 3803          dpnp->pr_files[i] = vp = PTOV(pnp);
3804 3804  
3805 3805          /*
3806 3806           * Link new vnode into list of all /proc vnodes for the process.
3807 3807           */
3808 3808          if (vp->v_type == VPROC) {
3809 3809                  pnp->pr_next = p->p_plist;
3810 3810                  p->p_plist = vp;
3811 3811          }
3812 3812          mutex_exit(&dpnp->pr_mutex);
3813 3813          prunlock(dpnp);
3814 3814          return (vp);
3815 3815  }
3816 3816  
3817 3817  static vnode_t *
3818 3818  pr_lookup_objectdir(vnode_t *dp, char *comp)
3819 3819  {
3820 3820          prnode_t *dpnp = VTOP(dp);
3821 3821          prnode_t *pnp;
3822 3822          proc_t *p;
3823 3823          struct seg *seg;
3824 3824          struct as *as;
3825 3825          vnode_t *vp;
3826 3826          vattr_t vattr;
3827 3827  
3828 3828          ASSERT(dpnp->pr_type == PR_OBJECTDIR);
3829 3829  
3830 3830          pnp = prgetnode(dp, PR_OBJECT);
3831 3831  
3832 3832          if (prlock(dpnp, ZNO) != 0) {
3833 3833                  prfreenode(pnp);
3834 3834                  return (NULL);
3835 3835          }
3836 3836          p = dpnp->pr_common->prc_proc;
3837 3837          if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
3838 3838                  prunlock(dpnp);
3839 3839                  prfreenode(pnp);
3840 3840                  return (NULL);
3841 3841          }
3842 3842  
3843 3843          /*
3844 3844           * We drop p_lock before grabbing the address space lock
3845 3845           * in order to avoid a deadlock with the clock thread.
3846 3846           * The process will not disappear and its address space
3847 3847           * will not change because it is marked P_PR_LOCK.
3848 3848           */
3849 3849          mutex_exit(&p->p_lock);
3850 3850          AS_LOCK_ENTER(as, RW_READER);
3851 3851          if ((seg = AS_SEGFIRST(as)) == NULL) {
3852 3852                  vp = NULL;
3853 3853                  goto out;
3854 3854          }
3855 3855          if (strcmp(comp, "a.out") == 0) {
3856 3856                  vp = p->p_exec;
3857 3857                  goto out;
3858 3858          }
3859 3859          do {
3860 3860                  /*
3861 3861                   * Manufacture a filename for the "object" directory.
3862 3862                   */
3863 3863                  vattr.va_mask = AT_FSID|AT_NODEID;
3864 3864                  if (seg->s_ops == &segvn_ops &&
3865 3865                      SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
3866 3866                      vp != NULL && vp->v_type == VREG &&
3867 3867                      VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
3868 3868                          char name[64];
3869 3869  
3870 3870                          if (vp == p->p_exec)    /* "a.out" */
3871 3871                                  continue;
3872 3872                          pr_object_name(name, vp, &vattr);
3873 3873                          if (strcmp(name, comp) == 0)
3874 3874                                  goto out;
3875 3875                  }
3876 3876          } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
3877 3877  
3878 3878          vp = NULL;
3879 3879  out:
3880 3880          if (vp != NULL) {
3881 3881                  VN_HOLD(vp);
3882 3882          }
3883 3883          AS_LOCK_EXIT(as);
3884 3884          mutex_enter(&p->p_lock);
3885 3885          prunlock(dpnp);
3886 3886  
3887 3887          if (vp == NULL)
3888 3888                  prfreenode(pnp);
3889 3889          else {
3890 3890                  /*
3891 3891                   * Fill in the prnode so future references will
3892 3892                   * be able to find the underlying object's vnode.
3893 3893                   * Don't link this prnode into the list of all
3894 3894                   * prnodes for the process; this is a one-use node.
3895 3895                   * Its use is entirely to catch and fail opens for writing.
3896 3896                   */
3897 3897                  pnp->pr_realvp = vp;
3898 3898                  vp = PTOV(pnp);
3899 3899          }
3900 3900  
3901 3901          return (vp);
3902 3902  }
3903 3903  
3904 3904  /*
3905 3905   * Find or construct an lwp vnode for the given lwpid.
3906 3906   */
3907 3907  static vnode_t *
3908 3908  pr_lookup_lwpdir(vnode_t *dp, char *comp)
3909 3909  {
3910 3910          id_t tid;       /* same type as t->t_tid */
3911 3911          int want_agent;
3912 3912          prnode_t *dpnp = VTOP(dp);
3913 3913          prnode_t *pnp;
3914 3914          prcommon_t *pcp;
3915 3915          vnode_t *vp;
3916 3916          proc_t *p;
3917 3917          kthread_t *t;
3918 3918          lwpdir_t *ldp;
3919 3919          lwpent_t *lep;
3920 3920          int tslot;
3921 3921          int c;
3922 3922  
3923 3923          ASSERT(dpnp->pr_type == PR_LWPDIR);
3924 3924  
3925 3925          tid = 0;
3926 3926          if (strcmp(comp, "agent") == 0)
3927 3927                  want_agent = 1;
3928 3928          else {
3929 3929                  want_agent = 0;
3930 3930                  while ((c = *comp++) != '\0') {
3931 3931                          id_t otid;
3932 3932  
3933 3933                          if (c < '0' || c > '9')
3934 3934                                  return (NULL);
3935 3935                          otid = tid;
3936 3936                          tid = 10*tid + c - '0';
3937 3937                          if (tid/10 != otid)     /* integer overflow */
3938 3938                                  return (NULL);
3939 3939                  }
3940 3940          }
3941 3941  
3942 3942          pnp = prgetnode(dp, PR_LWPIDDIR);
3943 3943  
3944 3944          p = pr_p_lock(dpnp);
3945 3945          mutex_exit(&pr_pidlock);
3946 3946          if (p == NULL) {
3947 3947                  prfreenode(pnp);
3948 3948                  return (NULL);
3949 3949          }
3950 3950  
3951 3951          if (want_agent) {
3952 3952                  if ((t = p->p_agenttp) == NULL)
3953 3953                          lep = NULL;
3954 3954                  else {
3955 3955                          tid = t->t_tid;
3956 3956                          tslot = t->t_dslot;
3957 3957                          lep = p->p_lwpdir[tslot].ld_entry;
3958 3958                  }
3959 3959          } else {
3960 3960                  if ((ldp = lwp_hash_lookup(p, tid)) == NULL)
3961 3961                          lep = NULL;
3962 3962                  else {
3963 3963                          tslot = (int)(ldp - p->p_lwpdir);
3964 3964                          lep = ldp->ld_entry;
3965 3965                  }
3966 3966          }
3967 3967  
3968 3968          if (lep == NULL) {
3969 3969                  prunlock(dpnp);
3970 3970                  prfreenode(pnp);
3971 3971                  return (NULL);
3972 3972          }
3973 3973  
3974 3974          /*
3975 3975           * If an lwp vnode already exists and it is not invalid
3976 3976           * and it was created by the current process and it belongs
3977 3977           * to the same /proc mount point as our parent vnode, then
3978 3978           * just use it and discard the newly-allocated prnode.
3979 3979           */
3980 3980          for (vp = lep->le_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3981 3981                  if (!(VTOP(vp)->pr_flags & PR_INVAL) &&
3982 3982                      VTOP(vp)->pr_owner == curproc &&
3983 3983                      vp->v_vfsp == dp->v_vfsp) {
3984 3984                          VN_HOLD(vp);
3985 3985                          prunlock(dpnp);
3986 3986                          prfreenode(pnp);
3987 3987                          return (vp);
3988 3988                  }
3989 3989          }
3990 3990          pnp->pr_owner = curproc;
3991 3991  
3992 3992          /*
3993 3993           * prgetnode() initialized most of the prnode.
3994 3994           * Finish the job.
3995 3995           */
3996 3996          pcp = pnp->pr_common;   /* the newly-allocated prcommon struct */
3997 3997          if ((vp = lep->le_trace) != NULL) {
3998 3998                  /* discard the new prcommon and use the existing prcommon */
3999 3999                  prfreecommon(pcp);
4000 4000                  pcp = VTOP(vp)->pr_common;
4001 4001                  mutex_enter(&pcp->prc_mutex);
4002 4002                  ASSERT(pcp->prc_refcnt > 0);
4003 4003                  pcp->prc_refcnt++;
4004 4004                  mutex_exit(&pcp->prc_mutex);
4005 4005                  pnp->pr_common = pcp;
4006 4006          } else {
4007 4007                  /* initialize the new prcommon struct */
4008 4008                  pcp->prc_flags |= PRC_LWP;
4009 4009                  if ((p->p_flag & SSYS) || p->p_as == &kas)
4010 4010                          pcp->prc_flags |= PRC_SYS;
4011 4011                  if ((t = lep->le_thread) == NULL)
4012 4012                          pcp->prc_flags |= PRC_DESTROY;
4013 4013                  pcp->prc_proc = p;
4014 4014                  pcp->prc_datamodel = dpnp->pr_pcommon->prc_datamodel;
4015 4015                  pcp->prc_pid = p->p_pid;
4016 4016                  pcp->prc_slot = p->p_slot;
4017 4017                  pcp->prc_thread = t;
4018 4018                  pcp->prc_tid = tid;
4019 4019                  pcp->prc_tslot = tslot;
4020 4020          }
4021 4021          pnp->pr_pcommon = dpnp->pr_pcommon;
4022 4022          pnp->pr_parent = dp;
4023 4023          VN_HOLD(dp);
4024 4024          /*
4025 4025           * Link in the old, invalid directory vnode so we
4026 4026           * can later determine the last close of the file.
4027 4027           */
4028 4028          pnp->pr_next = lep->le_trace;
4029 4029          lep->le_trace = vp = PTOV(pnp);
4030 4030          prunlock(dpnp);
4031 4031          return (vp);
4032 4032  }
4033 4033  
4034 4034  static vnode_t *
4035 4035  pr_lookup_lwpiddir(vnode_t *dp, char *comp)
4036 4036  {
4037 4037          prnode_t *dpnp = VTOP(dp);
4038 4038          vnode_t *vp;
4039 4039          prnode_t *pnp;
4040 4040          proc_t *p;
4041 4041          prdirent_t *dirp;
4042 4042          int i;
4043 4043          enum prnodetype type;
4044 4044  
4045 4045          ASSERT(dpnp->pr_type == PR_LWPIDDIR);
4046 4046  
4047 4047          for (i = 0; i < NLWPIDDIRFILES; i++) {
4048 4048                  /* Skip "." and ".." */
4049 4049                  dirp = &lwpiddir[i+2];
4050 4050                  if (strcmp(comp, dirp->d_name) == 0)
4051 4051                          break;
4052 4052          }
4053 4053  
4054 4054          if (i >= NLWPIDDIRFILES)
4055 4055                  return (NULL);
4056 4056  
4057 4057          type = (int)dirp->d_ino;
4058 4058          pnp = prgetnode(dp, type);
4059 4059  
4060 4060          p = pr_p_lock(dpnp);
4061 4061          mutex_exit(&pr_pidlock);
4062 4062          if (p == NULL) {
4063 4063                  prfreenode(pnp);
4064 4064                  return (NULL);
4065 4065          }
4066 4066          if (dpnp->pr_common->prc_flags & PRC_DESTROY) {
4067 4067                  /*
4068 4068                   * Only the lwpsinfo file is present for zombie lwps.
4069 4069                   * Nothing is present if the lwp has been reaped.
4070 4070                   */
4071 4071                  if (dpnp->pr_common->prc_tslot == -1 ||
4072 4072                      type != PR_LWPSINFO) {
4073 4073                          prunlock(dpnp);
4074 4074                          prfreenode(pnp);
4075 4075                          return (NULL);
4076 4076                  }
4077 4077          }
4078 4078  
4079 4079  #if defined(__sparc)
4080 4080          /* the asrs file exists only for sparc v9 _LP64 processes */
4081 4081          if (type == PR_ASRS && p->p_model != DATAMODEL_LP64) {
4082 4082                  prunlock(dpnp);
4083 4083                  prfreenode(pnp);
4084 4084                  return (NULL);
4085 4085          }
4086 4086  #endif
4087 4087  
4088 4088          mutex_enter(&dpnp->pr_mutex);
4089 4089  
4090 4090          if ((vp = dpnp->pr_files[i]) != NULL &&
4091 4091              !(VTOP(vp)->pr_flags & PR_INVAL)) {
4092 4092                  VN_HOLD(vp);
4093 4093                  mutex_exit(&dpnp->pr_mutex);
4094 4094                  prunlock(dpnp);
4095 4095                  prfreenode(pnp);
4096 4096                  return (vp);
4097 4097          }
4098 4098  
4099 4099          /*
4100 4100           * prgetnode() initialized most of the prnode.
4101 4101           * Finish the job.
4102 4102           */
4103 4103          pnp->pr_common = dpnp->pr_common;
4104 4104          pnp->pr_pcommon = dpnp->pr_pcommon;
4105 4105          pnp->pr_parent = dp;
4106 4106          VN_HOLD(dp);
4107 4107          pnp->pr_index = i;
4108 4108  
4109 4109          dpnp->pr_files[i] = vp = PTOV(pnp);
4110 4110  
4111 4111          /*
4112 4112           * Link new vnode into list of all /proc vnodes for the process.
4113 4113           */
4114 4114          if (vp->v_type == VPROC) {
4115 4115                  pnp->pr_next = p->p_plist;
4116 4116                  p->p_plist = vp;
4117 4117          }
4118 4118          mutex_exit(&dpnp->pr_mutex);
4119 4119          prunlock(dpnp);
4120 4120          return (vp);
4121 4121  }
4122 4122  
4123 4123  /*
4124 4124   * Lookup one of the process's open files.
4125 4125   */
4126 4126  static vnode_t *
4127 4127  pr_lookup_fddir(vnode_t *dp, char *comp)
4128 4128  {
4129 4129          prnode_t *dpnp = VTOP(dp);
4130 4130          prnode_t *pnp;
4131 4131          vnode_t *vp = NULL;
4132 4132          proc_t *p;
4133 4133          file_t *fp;
4134 4134          uint_t fd;
4135 4135          int c;
4136 4136          uf_entry_t *ufp;
4137 4137          uf_info_t *fip;
4138 4138  
4139 4139          ASSERT(dpnp->pr_type == PR_FDDIR);
4140 4140  
4141 4141          fd = 0;
4142 4142          while ((c = *comp++) != '\0') {
4143 4143                  int ofd;
4144 4144                  if (c < '0' || c > '9')
4145 4145                          return (NULL);
4146 4146                  ofd = fd;
4147 4147                  fd = 10*fd + c - '0';
4148 4148                  if (fd/10 != ofd)       /* integer overflow */
4149 4149                          return (NULL);
4150 4150          }
4151 4151  
4152 4152          pnp = prgetnode(dp, PR_FD);
4153 4153  
4154 4154          if (prlock(dpnp, ZNO) != 0) {
4155 4155                  prfreenode(pnp);
4156 4156                  return (NULL);
4157 4157          }
4158 4158          p = dpnp->pr_common->prc_proc;
4159 4159          if ((p->p_flag & SSYS) || p->p_as == &kas) {
4160 4160                  prunlock(dpnp);
4161 4161                  prfreenode(pnp);
4162 4162                  return (NULL);
4163 4163          }
4164 4164  
4165 4165          fip = P_FINFO(p);
4166 4166          mutex_exit(&p->p_lock);
4167 4167          mutex_enter(&fip->fi_lock);
4168 4168          if (fd < fip->fi_nfiles) {
4169 4169                  UF_ENTER(ufp, fip, fd);
4170 4170                  if ((fp = ufp->uf_file) != NULL) {
4171 4171                          pnp->pr_mode = 07111;
4172 4172                          if (fp->f_flag & FREAD)
4173 4173                                  pnp->pr_mode |= 0444;
4174 4174                          if (fp->f_flag & FWRITE)
4175 4175                                  pnp->pr_mode |= 0222;
4176 4176                          vp = fp->f_vnode;
4177 4177                          VN_HOLD(vp);
4178 4178                  }
4179 4179                  UF_EXIT(ufp);
4180 4180          }
4181 4181          mutex_exit(&fip->fi_lock);
4182 4182          mutex_enter(&p->p_lock);
4183 4183          prunlock(dpnp);
4184 4184  
4185 4185          if (vp == NULL)
4186 4186                  prfreenode(pnp);
4187 4187          else {
4188 4188                  /*
4189 4189                   * Fill in the prnode so future references will
4190 4190                   * be able to find the underlying object's vnode.
4191 4191                   * Don't link this prnode into the list of all
4192 4192                   * prnodes for the process; this is a one-use node.
4193 4193                   */
4194 4194                  pnp->pr_realvp = vp;
4195 4195                  pnp->pr_parent = dp;            /* needed for prlookup */
4196 4196                  VN_HOLD(dp);
4197 4197                  vp = PTOV(pnp);
4198 4198                  if (pnp->pr_realvp->v_type == VDIR)
4199 4199                          vp->v_type = VDIR;
4200 4200          }
4201 4201  
4202 4202          return (vp);
4203 4203  }
4204 4204  
4205 4205  static vnode_t *
4206 4206  pr_lookup_pathdir(vnode_t *dp, char *comp)
4207 4207  {
4208 4208          prnode_t *dpnp = VTOP(dp);
4209 4209          prnode_t *pnp;
4210 4210          vnode_t *vp = NULL;
4211 4211          proc_t *p;
4212 4212          uint_t fd, flags = 0;
4213 4213          int c;
4214 4214          uf_entry_t *ufp;
4215 4215          uf_info_t *fip;
4216 4216          enum { NAME_FD, NAME_OBJECT, NAME_ROOT, NAME_CWD, NAME_UNKNOWN } type;
4217 4217          char *tmp;
4218 4218          int idx;
4219 4219          struct seg *seg;
4220 4220          struct as *as = NULL;
4221 4221          vattr_t vattr;
4222 4222  
4223 4223          ASSERT(dpnp->pr_type == PR_PATHDIR);
4224 4224  
4225 4225          /*
4226 4226           * First, check if this is a numeric entry, in which case we have a
4227 4227           * file descriptor.
4228 4228           */
4229 4229          fd = 0;
4230 4230          type = NAME_FD;
4231 4231          tmp = comp;
4232 4232          while ((c = *tmp++) != '\0') {
4233 4233                  int ofd;
4234 4234                  if (c < '0' || c > '9') {
4235 4235                          type = NAME_UNKNOWN;
4236 4236                          break;
4237 4237                  }
4238 4238                  ofd = fd;
4239 4239                  fd = 10*fd + c - '0';
4240 4240                  if (fd/10 != ofd) {     /* integer overflow */
4241 4241                          type = NAME_UNKNOWN;
4242 4242                          break;
4243 4243                  }
4244 4244          }
4245 4245  
4246 4246          /*
4247 4247           * Next, see if it is one of the special values {root, cwd}.
4248 4248           */
4249 4249          if (type == NAME_UNKNOWN) {
4250 4250                  if (strcmp(comp, "root") == 0)
4251 4251                          type = NAME_ROOT;
4252 4252                  else if (strcmp(comp, "cwd") == 0)
4253 4253                          type = NAME_CWD;
4254 4254          }
4255 4255  
4256 4256          /*
4257 4257           * Grab the necessary data from the process
4258 4258           */
4259 4259          if (prlock(dpnp, ZNO) != 0)
4260 4260                  return (NULL);
4261 4261          p = dpnp->pr_common->prc_proc;
4262 4262  
4263 4263          fip = P_FINFO(p);
4264 4264  
4265 4265          switch (type) {
4266 4266          case NAME_ROOT:
4267 4267                  if ((vp = PTOU(p)->u_rdir) == NULL)
4268 4268                          vp = p->p_zone->zone_rootvp;
4269 4269                  VN_HOLD(vp);
4270 4270                  break;
4271 4271          case NAME_CWD:
4272 4272                  vp = PTOU(p)->u_cdir;
4273 4273                  VN_HOLD(vp);
4274 4274                  break;
4275 4275          default:
4276 4276                  if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
4277 4277                          prunlock(dpnp);
4278 4278                          return (NULL);
4279 4279                  }
4280 4280          }
4281 4281          mutex_exit(&p->p_lock);
4282 4282  
4283 4283          /*
4284 4284           * Determine if this is an object entry
4285 4285           */
4286 4286          if (type == NAME_UNKNOWN) {
4287 4287                  /*
4288 4288                   * Start with the inode index immediately after the number of
4289 4289                   * files.
4290 4290                   */
4291 4291                  mutex_enter(&fip->fi_lock);
4292 4292                  idx = fip->fi_nfiles + 4;
4293 4293                  mutex_exit(&fip->fi_lock);
4294 4294  
4295 4295                  if (strcmp(comp, "a.out") == 0) {
4296 4296                          if (p->p_execdir != NULL) {
4297 4297                                  vp = p->p_execdir;
4298 4298                                  VN_HOLD(vp);
4299 4299                                  type = NAME_OBJECT;
4300 4300                                  flags |= PR_AOUT;
4301 4301                          } else {
4302 4302                                  vp = p->p_exec;
4303 4303                                  VN_HOLD(vp);
4304 4304                                  type = NAME_OBJECT;
4305 4305                          }
4306 4306                  } else {
4307 4307                          AS_LOCK_ENTER(as, RW_READER);
4308 4308                          if ((seg = AS_SEGFIRST(as)) != NULL) {
4309 4309                                  do {
4310 4310                                          /*
4311 4311                                           * Manufacture a filename for the
4312 4312                                           * "object" directory.
4313 4313                                           */
4314 4314                                          vattr.va_mask = AT_FSID|AT_NODEID;
4315 4315                                          if (seg->s_ops == &segvn_ops &&
4316 4316                                              SEGOP_GETVP(seg, seg->s_base, &vp)
4317 4317                                              == 0 &&
4318 4318                                              vp != NULL && vp->v_type == VREG &&
4319 4319                                              VOP_GETATTR(vp, &vattr, 0, CRED(),
4320 4320                                              NULL) == 0) {
4321 4321                                                  char name[64];
4322 4322  
4323 4323                                                  if (vp == p->p_exec)
4324 4324                                                          continue;
4325 4325                                                  idx++;
4326 4326                                                  pr_object_name(name, vp,
4327 4327                                                      &vattr);
4328 4328                                                  if (strcmp(name, comp) == 0)
4329 4329                                                          break;
4330 4330                                          }
4331 4331                                  } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4332 4332                          }
4333 4333  
4334 4334                          if (seg == NULL) {
4335 4335                                  vp = NULL;
4336 4336                          } else {
4337 4337                                  VN_HOLD(vp);
4338 4338                                  type = NAME_OBJECT;
4339 4339                          }
4340 4340  
4341 4341                          AS_LOCK_EXIT(as);
4342 4342                  }
4343 4343          }
4344 4344  
4345 4345  
4346 4346          switch (type) {
4347 4347          case NAME_FD:
4348 4348                  mutex_enter(&fip->fi_lock);
4349 4349                  if (fd < fip->fi_nfiles) {
4350 4350                          UF_ENTER(ufp, fip, fd);
4351 4351                          if (ufp->uf_file != NULL) {
4352 4352                                  vp = ufp->uf_file->f_vnode;
4353 4353                                  VN_HOLD(vp);
4354 4354                          }
4355 4355                          UF_EXIT(ufp);
4356 4356                  }
4357 4357                  mutex_exit(&fip->fi_lock);
4358 4358                  idx = fd + 4;
4359 4359                  break;
4360 4360          case NAME_ROOT:
4361 4361                  idx = 2;
4362 4362                  break;
4363 4363          case NAME_CWD:
4364 4364                  idx = 3;
4365 4365                  break;
4366 4366          case NAME_OBJECT:
4367 4367          case NAME_UNKNOWN:
4368 4368                  /* Nothing to do */
4369 4369                  break;
4370 4370          }
4371 4371  
4372 4372          mutex_enter(&p->p_lock);
4373 4373          prunlock(dpnp);
4374 4374  
4375 4375          if (vp != NULL) {
4376 4376                  pnp = prgetnode(dp, PR_PATH);
4377 4377  
4378 4378                  pnp->pr_flags |= flags;
4379 4379                  pnp->pr_common = dpnp->pr_common;
4380 4380                  pnp->pr_pcommon = dpnp->pr_pcommon;
4381 4381                  pnp->pr_realvp = vp;
4382 4382                  pnp->pr_parent = dp;            /* needed for prlookup */
4383 4383                  pnp->pr_ino = pmkino(idx, dpnp->pr_common->prc_slot, PR_PATH);
4384 4384                  VN_HOLD(dp);
4385 4385                  vp = PTOV(pnp);
4386 4386                  vp->v_type = VLNK;
4387 4387          }
4388 4388  
4389 4389          return (vp);
4390 4390  }
4391 4391  
4392 4392  /*
4393 4393   * Look up one of the process's active templates.
4394 4394   */
4395 4395  static vnode_t *
4396 4396  pr_lookup_tmpldir(vnode_t *dp, char *comp)
4397 4397  {
4398 4398          prnode_t *dpnp = VTOP(dp);
4399 4399          prnode_t *pnp;
4400 4400          vnode_t *vp = NULL;
4401 4401          proc_t *p;
4402 4402          int i;
4403 4403  
4404 4404          ASSERT(dpnp->pr_type == PR_TMPLDIR);
4405 4405  
4406 4406          for (i = 0; i < ct_ntypes; i++)
4407 4407                  if (strcmp(comp, ct_types[i]->ct_type_name) == 0)
4408 4408                          break;
4409 4409          if (i == ct_ntypes)
4410 4410                  return (NULL);
4411 4411  
4412 4412          pnp = prgetnode(dp, PR_TMPL);
4413 4413  
4414 4414          if (prlock(dpnp, ZNO) != 0) {
4415 4415                  prfreenode(pnp);
4416 4416                  return (NULL);
4417 4417          }
4418 4418          p = dpnp->pr_common->prc_proc;
4419 4419          if ((p->p_flag & SSYS) || p->p_as == &kas ||
4420 4420              (dpnp->pr_common->prc_flags & (PRC_DESTROY | PRC_LWP)) != PRC_LWP) {
4421 4421                  prunlock(dpnp);
4422 4422                  prfreenode(pnp);
4423 4423                  return (NULL);
4424 4424          }
4425 4425          if (ttolwp(dpnp->pr_common->prc_thread)->lwp_ct_active[i] != NULL) {
4426 4426                  pnp->pr_common = dpnp->pr_common;
4427 4427                  pnp->pr_pcommon = dpnp->pr_pcommon;
4428 4428                  pnp->pr_parent = dp;
4429 4429                  pnp->pr_cttype = i;
4430 4430                  VN_HOLD(dp);
4431 4431                  vp = PTOV(pnp);
4432 4432          } else {
4433 4433                  prfreenode(pnp);
4434 4434          }
4435 4435          prunlock(dpnp);
4436 4436  
4437 4437          return (vp);
4438 4438  }
4439 4439  
4440 4440  /*
4441 4441   * Look up one of the contracts owned by the process.
4442 4442   */
4443 4443  static vnode_t *
4444 4444  pr_lookup_ctdir(vnode_t *dp, char *comp)
4445 4445  {
4446 4446          prnode_t *dpnp = VTOP(dp);
4447 4447          prnode_t *pnp;
4448 4448          vnode_t *vp = NULL;
4449 4449          proc_t *p;
4450 4450          id_t id = 0;
4451 4451          contract_t *ct;
4452 4452          int c;
4453 4453  
4454 4454          ASSERT(dpnp->pr_type == PR_CTDIR);
4455 4455  
4456 4456          while ((c = *comp++) != '\0') {
4457 4457                  id_t oid;
4458 4458                  if (c < '0' || c > '9')
4459 4459                          return (NULL);
4460 4460                  oid = id;
4461 4461                  id = 10 * id + c - '0';
4462 4462                  if (id / 10 != oid)     /* integer overflow */
4463 4463                          return (NULL);
4464 4464          }
4465 4465  
4466 4466          /*
4467 4467           * Search all contracts; we'll filter below.
4468 4468           */
4469 4469          ct = contract_ptr(id, GLOBAL_ZONEUNIQID);
4470 4470          if (ct == NULL)
4471 4471                  return (NULL);
4472 4472  
4473 4473          pnp = prgetnode(dp, PR_CT);
4474 4474  
4475 4475          if (prlock(dpnp, ZNO) != 0) {
4476 4476                  prfreenode(pnp);
4477 4477                  contract_rele(ct);
4478 4478                  return (NULL);
4479 4479          }
4480 4480          p = dpnp->pr_common->prc_proc;
4481 4481          /*
4482 4482           * We only allow lookups of contracts owned by this process, or,
4483 4483           * if we are zsched and this is a zone's procfs, contracts on
4484 4484           * stuff in the zone which are held by processes or contracts
4485 4485           * outside the zone.  (see logic in contract_status_common)
4486 4486           */
4487 4487          if ((ct->ct_owner != p) &&
4488 4488              !(p == VTOZONE(dp)->zone_zsched && ct->ct_state < CTS_ORPHAN &&
4489 4489              VTOZONE(dp)->zone_uniqid == contract_getzuniqid(ct) &&
4490 4490              VTOZONE(dp)->zone_uniqid != GLOBAL_ZONEUNIQID &&
4491 4491              ct->ct_czuniqid == GLOBAL_ZONEUNIQID)) {
4492 4492                  prunlock(dpnp);
4493 4493                  prfreenode(pnp);
4494 4494                  contract_rele(ct);
4495 4495                  return (NULL);
4496 4496          }
4497 4497          pnp->pr_common = dpnp->pr_common;
4498 4498          pnp->pr_pcommon = dpnp->pr_pcommon;
4499 4499          pnp->pr_contract = ct;
4500 4500          pnp->pr_parent = dp;
4501 4501          pnp->pr_ino = pmkino(id, pnp->pr_common->prc_slot, PR_CT);
4502 4502          VN_HOLD(dp);
4503 4503          prunlock(dpnp);
4504 4504          vp = PTOV(pnp);
4505 4505  
4506 4506          return (vp);
4507 4507  }
4508 4508  
4509 4509  /*
4510 4510   * Construct an lwp vnode for the old /proc interface.
4511 4511   * We stand on our head to make the /proc plumbing correct.
4512 4512   */
4513 4513  vnode_t *
4514 4514  prlwpnode(prnode_t *pnp, uint_t tid)
4515 4515  {
4516 4516          char comp[12];
4517 4517          vnode_t *dp;
4518 4518          vnode_t *vp;
4519 4519          prcommon_t *pcp;
4520 4520          proc_t *p;
4521 4521  
4522 4522          /*
4523 4523           * Lookup the /proc/<pid>/lwp/<lwpid> directory vnode.
4524 4524           */
4525 4525          if (pnp->pr_type == PR_PIDFILE) {
4526 4526                  dp = pnp->pr_parent;            /* /proc/<pid> */
4527 4527                  VN_HOLD(dp);
4528 4528                  vp = pr_lookup_piddir(dp, "lwp");
4529 4529                  VN_RELE(dp);
4530 4530                  if ((dp = vp) == NULL)          /* /proc/<pid>/lwp */
4531 4531                          return (NULL);
4532 4532          } else if (pnp->pr_type == PR_LWPIDFILE) {
4533 4533                  dp = pnp->pr_parent;            /* /proc/<pid>/lwp/<lwpid> */
4534 4534                  dp = VTOP(dp)->pr_parent;       /* /proc/<pid>/lwp */
4535 4535                  VN_HOLD(dp);
4536 4536          } else {
4537 4537                  return (NULL);
4538 4538          }
4539 4539  
4540 4540          (void) pr_u32tos(tid, comp, sizeof (comp));
4541 4541          vp = pr_lookup_lwpdir(dp, comp);
4542 4542          VN_RELE(dp);
4543 4543          if ((dp = vp) == NULL)
4544 4544                  return (NULL);
4545 4545  
4546 4546          pnp = prgetnode(dp, PR_LWPIDFILE);
4547 4547          vp = PTOV(pnp);
4548 4548  
4549 4549          /*
4550 4550           * prgetnode() initialized most of the prnode.
4551 4551           * Finish the job.
4552 4552           */
4553 4553          pcp = VTOP(dp)->pr_common;
4554 4554          pnp->pr_ino = ptoi(pcp->prc_pid);
4555 4555          pnp->pr_common = pcp;
4556 4556          pnp->pr_pcommon = VTOP(dp)->pr_pcommon;
4557 4557          pnp->pr_parent = dp;
4558 4558          /*
4559 4559           * Link new vnode into list of all /proc vnodes for the process.
4560 4560           */
4561 4561          p = pr_p_lock(pnp);
4562 4562          mutex_exit(&pr_pidlock);
4563 4563          if (p == NULL) {
4564 4564                  VN_RELE(dp);
4565 4565                  prfreenode(pnp);
4566 4566                  vp = NULL;
4567 4567          } else if (pcp->prc_thread == NULL) {
4568 4568                  prunlock(pnp);
4569 4569                  VN_RELE(dp);
4570 4570                  prfreenode(pnp);
4571 4571                  vp = NULL;
4572 4572          } else {
4573 4573                  pnp->pr_next = p->p_plist;
4574 4574                  p->p_plist = vp;
4575 4575                  prunlock(pnp);
4576 4576          }
4577 4577  
4578 4578          return (vp);
4579 4579  }
4580 4580  
4581 4581  #if defined(DEBUG)
4582 4582  
4583 4583  static  uint32_t nprnode;
4584 4584  static  uint32_t nprcommon;
4585 4585  
4586 4586  #define INCREMENT(x)    atomic_inc_32(&x);
4587 4587  #define DECREMENT(x)    atomic_dec_32(&x);
4588 4588  
4589 4589  #else
4590 4590  
4591 4591  #define INCREMENT(x)
4592 4592  #define DECREMENT(x)
4593 4593  
4594 4594  #endif  /* DEBUG */
4595 4595  
4596 4596  /*
4597 4597   * New /proc vnode required; allocate it and fill in most of the fields.
4598 4598   */
4599 4599  prnode_t *
4600 4600  prgetnode(vnode_t *dp, prnodetype_t type)
4601 4601  {
4602 4602          prnode_t *pnp;
4603 4603          prcommon_t *pcp;
4604 4604          vnode_t *vp;
4605 4605          ulong_t nfiles;
4606 4606  
4607 4607          INCREMENT(nprnode);
4608 4608          pnp = kmem_zalloc(sizeof (prnode_t), KM_SLEEP);
4609 4609  
4610 4610          mutex_init(&pnp->pr_mutex, NULL, MUTEX_DEFAULT, NULL);
4611 4611          pnp->pr_type = type;
4612 4612  
4613 4613          pnp->pr_vnode = vn_alloc(KM_SLEEP);
4614 4614  
4615 4615          vp = PTOV(pnp);
4616 4616          vp->v_flag = VNOCACHE|VNOMAP|VNOSWAP|VNOMOUNT;
4617 4617          vn_setops(vp, prvnodeops);
4618 4618          vp->v_vfsp = dp->v_vfsp;
4619 4619          vp->v_type = VPROC;
4620 4620          vp->v_data = (caddr_t)pnp;
4621 4621  
4622 4622          switch (type) {
4623 4623          case PR_PIDDIR:
4624 4624          case PR_LWPIDDIR:
4625 4625                  /*
4626 4626                   * We need a prcommon and a files array for each of these.
4627 4627                   */
4628 4628                  INCREMENT(nprcommon);
4629 4629  
4630 4630                  pcp = kmem_zalloc(sizeof (prcommon_t), KM_SLEEP);
4631 4631                  pcp->prc_refcnt = 1;
4632 4632                  pnp->pr_common = pcp;
4633 4633                  mutex_init(&pcp->prc_mutex, NULL, MUTEX_DEFAULT, NULL);
4634 4634                  cv_init(&pcp->prc_wait, NULL, CV_DEFAULT, NULL);
4635 4635  
4636 4636                  nfiles = (type == PR_PIDDIR)? NPIDDIRFILES : NLWPIDDIRFILES;
4637 4637                  pnp->pr_files =
4638 4638                      kmem_zalloc(nfiles * sizeof (vnode_t *), KM_SLEEP);
4639 4639  
4640 4640                  vp->v_type = VDIR;
4641 4641                  /*
4642 4642                   * Mode should be read-search by all, but we cannot so long
4643 4643                   * as we must support compatibility mode with old /proc.
4644 4644                   * Make /proc/<pid> be read by owner only, search by all.
4645 4645                   * Make /proc/<pid>/lwp/<lwpid> read-search by all.  Also,
4646 4646                   * set VDIROPEN on /proc/<pid> so it can be opened for writing.
4647 4647                   */
4648 4648                  if (type == PR_PIDDIR) {
4649 4649                          /* kludge for old /proc interface */
4650 4650                          prnode_t *xpnp = prgetnode(dp, PR_PIDFILE);
4651 4651                          pnp->pr_pidfile = PTOV(xpnp);
4652 4652                          pnp->pr_mode = 0511;
4653 4653                          vp->v_flag |= VDIROPEN;
4654 4654                  } else {
4655 4655                          pnp->pr_mode = 0555;
4656 4656                  }
4657 4657  
4658 4658                  break;
4659 4659  
4660 4660          case PR_CURDIR:
4661 4661          case PR_ROOTDIR:
4662 4662          case PR_FDDIR:
4663 4663          case PR_OBJECTDIR:
4664 4664          case PR_PATHDIR:
4665 4665          case PR_CTDIR:
4666 4666          case PR_TMPLDIR:
4667 4667                  vp->v_type = VDIR;
4668 4668                  pnp->pr_mode = 0500;    /* read-search by owner only */
4669 4669                  break;
4670 4670  
4671 4671          case PR_CT:
4672 4672                  vp->v_type = VLNK;
4673 4673                  pnp->pr_mode = 0500;    /* read-search by owner only */
4674 4674                  break;
4675 4675  
4676 4676          case PR_PATH:
4677 4677          case PR_SELF:
4678 4678                  vp->v_type = VLNK;
4679 4679                  pnp->pr_mode = 0777;
4680 4680                  break;
4681 4681  
4682 4682          case PR_LWPDIR:
4683 4683                  vp->v_type = VDIR;
4684 4684                  pnp->pr_mode = 0555;    /* read-search by all */
4685 4685                  break;
4686 4686  
4687 4687          case PR_AS:
4688 4688          case PR_TMPL:
4689 4689                  pnp->pr_mode = 0600;    /* read-write by owner only */
4690 4690                  break;
4691 4691  
4692 4692          case PR_CTL:
4693 4693          case PR_LWPCTL:
4694 4694                  pnp->pr_mode = 0200;    /* write-only by owner only */
4695 4695                  break;
4696 4696  
4697 4697          case PR_PIDFILE:
4698 4698          case PR_LWPIDFILE:
4699 4699                  pnp->pr_mode = 0600;    /* read-write by owner only */
4700 4700                  break;
4701 4701  
4702 4702          case PR_PSINFO:
4703 4703                  pnp->pr_mode = 0644;    /* readable by all + owner can write */
4704 4704                  break;
4705 4705  
4706 4706          case PR_LPSINFO:
4707 4707          case PR_LWPSINFO:
4708 4708          case PR_USAGE:
4709 4709          case PR_LUSAGE:
4710 4710          case PR_LWPUSAGE:
4711 4711          case PR_ARGV:
4712 4712                  pnp->pr_mode = 0444;    /* read-only by all */
4713 4713                  break;
4714 4714  
4715 4715          default:
4716 4716                  pnp->pr_mode = 0400;    /* read-only by owner only */
4717 4717                  break;
4718 4718          }
4719 4719          vn_exists(vp);
4720 4720          return (pnp);
4721 4721  }
4722 4722  
4723 4723  /*
4724 4724   * Free the storage obtained from prgetnode().
4725 4725   */
4726 4726  void
4727 4727  prfreenode(prnode_t *pnp)
4728 4728  {
4729 4729          vnode_t *vp;
4730 4730          ulong_t nfiles;
4731 4731  
4732 4732          vn_invalid(PTOV(pnp));
4733 4733          vn_free(PTOV(pnp));
4734 4734          mutex_destroy(&pnp->pr_mutex);
4735 4735  
4736 4736          switch (pnp->pr_type) {
4737 4737          case PR_PIDDIR:
4738 4738                  /* kludge for old /proc interface */
4739 4739                  if (pnp->pr_pidfile != NULL) {
4740 4740                          prfreenode(VTOP(pnp->pr_pidfile));
4741 4741                          pnp->pr_pidfile = NULL;
4742 4742                  }
4743 4743                  /* FALLTHROUGH */
4744 4744          case PR_LWPIDDIR:
4745 4745                  /*
4746 4746                   * We allocated a prcommon and a files array for each of these.
4747 4747                   */
4748 4748                  prfreecommon(pnp->pr_common);
4749 4749                  nfiles = (pnp->pr_type == PR_PIDDIR)?
4750 4750                      NPIDDIRFILES : NLWPIDDIRFILES;
4751 4751                  kmem_free(pnp->pr_files, nfiles * sizeof (vnode_t *));
4752 4752                  break;
4753 4753          default:
4754 4754                  break;
4755 4755          }
4756 4756          /*
4757 4757           * If there is an underlying vnode, be sure
4758 4758           * to release it after freeing the prnode.
4759 4759           */
4760 4760          vp = pnp->pr_realvp;
4761 4761          kmem_free(pnp, sizeof (*pnp));
4762 4762          DECREMENT(nprnode);
4763 4763          if (vp != NULL) {
4764 4764                  VN_RELE(vp);
4765 4765          }
4766 4766  }
4767 4767  
4768 4768  /*
4769 4769   * Free a prcommon structure, if the reference count reaches zero.
4770 4770   */
4771 4771  static void
4772 4772  prfreecommon(prcommon_t *pcp)
4773 4773  {
4774 4774          mutex_enter(&pcp->prc_mutex);
4775 4775          ASSERT(pcp->prc_refcnt > 0);
4776 4776          if (--pcp->prc_refcnt != 0)
4777 4777                  mutex_exit(&pcp->prc_mutex);
4778 4778          else {
4779 4779                  mutex_exit(&pcp->prc_mutex);
4780 4780                  ASSERT(pcp->prc_pollhead.ph_list == NULL);
4781 4781                  ASSERT(pcp->prc_refcnt == 0);
4782 4782                  ASSERT(pcp->prc_selfopens == 0 && pcp->prc_writers == 0);
4783 4783                  mutex_destroy(&pcp->prc_mutex);
4784 4784                  cv_destroy(&pcp->prc_wait);
4785 4785                  kmem_free(pcp, sizeof (prcommon_t));
4786 4786                  DECREMENT(nprcommon);
4787 4787          }
4788 4788  }
4789 4789  
4790 4790  /*
4791 4791   * Array of readdir functions, indexed by /proc file type.
4792 4792   */
4793 4793  static int pr_readdir_notdir(), pr_readdir_procdir(), pr_readdir_piddir(),
4794 4794          pr_readdir_objectdir(), pr_readdir_lwpdir(), pr_readdir_lwpiddir(),
4795 4795          pr_readdir_fddir(), pr_readdir_pathdir(), pr_readdir_tmpldir(),
4796 4796          pr_readdir_ctdir();
4797 4797  
4798 4798  static int (*pr_readdir_function[PR_NFILES])() = {
4799 4799          pr_readdir_procdir,     /* /proc                                */
4800 4800          pr_readdir_notdir,      /* /proc/self                           */
4801 4801          pr_readdir_piddir,      /* /proc/<pid>                          */
4802 4802          pr_readdir_notdir,      /* /proc/<pid>/as                       */
4803 4803          pr_readdir_notdir,      /* /proc/<pid>/ctl                      */
4804 4804          pr_readdir_notdir,      /* /proc/<pid>/status                   */
4805 4805          pr_readdir_notdir,      /* /proc/<pid>/lstatus                  */
4806 4806          pr_readdir_notdir,      /* /proc/<pid>/psinfo                   */
4807 4807          pr_readdir_notdir,      /* /proc/<pid>/lpsinfo                  */
4808 4808          pr_readdir_notdir,      /* /proc/<pid>/map                      */
4809 4809          pr_readdir_notdir,      /* /proc/<pid>/rmap                     */
4810 4810          pr_readdir_notdir,      /* /proc/<pid>/xmap                     */
4811 4811          pr_readdir_notdir,      /* /proc/<pid>/cred                     */
4812 4812          pr_readdir_notdir,      /* /proc/<pid>/sigact                   */
4813 4813          pr_readdir_notdir,      /* /proc/<pid>/auxv                     */
4814 4814  #if defined(__x86)
4815 4815          pr_readdir_notdir,      /* /proc/<pid>/ldt                      */
4816 4816  #endif
4817 4817          pr_readdir_notdir,      /* /proc/<pid>/argv                     */
4818 4818          pr_readdir_notdir,      /* /proc/<pid>/usage                    */
4819 4819          pr_readdir_notdir,      /* /proc/<pid>/lusage                   */
4820 4820          pr_readdir_notdir,      /* /proc/<pid>/pagedata                 */
4821 4821          pr_readdir_notdir,      /* /proc/<pid>/watch                    */
4822 4822          pr_readdir_notdir,      /* /proc/<pid>/cwd                      */
4823 4823          pr_readdir_notdir,      /* /proc/<pid>/root                     */
4824 4824          pr_readdir_fddir,       /* /proc/<pid>/fd                       */
4825 4825          pr_readdir_notdir,      /* /proc/<pid>/fd/nn                    */
4826 4826          pr_readdir_objectdir,   /* /proc/<pid>/object                   */
4827 4827          pr_readdir_notdir,      /* /proc/<pid>/object/xxx               */
4828 4828          pr_readdir_lwpdir,      /* /proc/<pid>/lwp                      */
4829 4829          pr_readdir_lwpiddir,    /* /proc/<pid>/lwp/<lwpid>              */
4830 4830          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpctl       */
4831 4831          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus    */
4832 4832          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpsinfo     */
4833 4833          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpusage     */
4834 4834          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/xregs        */
4835 4835          pr_readdir_tmpldir,     /* /proc/<pid>/lwp/<lwpid>/templates    */
4836 4836          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4837 4837          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/spymaster    */
4838 4838  #if defined(__sparc)
4839 4839          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/gwindows     */
4840 4840          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/asrs         */
4841 4841  #endif
4842 4842          pr_readdir_notdir,      /* /proc/<pid>/priv                     */
4843 4843          pr_readdir_pathdir,     /* /proc/<pid>/path                     */
4844 4844          pr_readdir_notdir,      /* /proc/<pid>/path/xxx                 */
4845 4845          pr_readdir_ctdir,       /* /proc/<pid>/contracts                */
4846 4846          pr_readdir_notdir,      /* /proc/<pid>/contracts/<ctid>         */
4847 4847          pr_readdir_notdir,      /* old process file                     */
4848 4848          pr_readdir_notdir,      /* old lwp file                         */
4849 4849          pr_readdir_notdir,      /* old pagedata file                    */
4850 4850  };
4851 4851  
4852 4852  /* ARGSUSED */
4853 4853  static int
4854 4854  prreaddir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
4855 4855          caller_context_t *ct, int flags)
4856 4856  {
4857 4857          prnode_t *pnp = VTOP(vp);
4858 4858  
4859 4859          ASSERT(pnp->pr_type < PR_NFILES);
4860 4860  
4861 4861          /* XXX - Do we need to pass ct and flags? */
4862 4862          return (pr_readdir_function[pnp->pr_type](pnp, uiop, eofp));
4863 4863  }
4864 4864  
4865 4865  /* ARGSUSED */
4866 4866  static int
4867 4867  pr_readdir_notdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4868 4868  {
4869 4869          return (ENOTDIR);
4870 4870  }
4871 4871  
4872 4872  /* ARGSUSED */
4873 4873  static int
4874 4874  pr_readdir_procdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4875 4875  {
4876 4876          zoneid_t zoneid;
4877 4877          gfs_readdir_state_t gstate;
4878 4878          int error, eof = 0;
4879 4879          offset_t n;
4880 4880  
4881 4881          ASSERT(pnp->pr_type == PR_PROCDIR);
4882 4882  
4883 4883          zoneid = VTOZONE(PTOV(pnp))->zone_id;
4884 4884  
4885 4885          if ((error = gfs_readdir_init(&gstate, PNSIZ, PRSDSIZE, uiop,
4886 4886              PRROOTINO, PRROOTINO, 0)) != 0)
4887 4887                  return (error);
4888 4888  
4889 4889          /*
4890 4890           * Loop until user's request is satisfied or until all processes
4891 4891           * have been examined.
4892 4892           */
4893 4893          while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
4894 4894                  uint_t pid;
4895 4895                  int pslot;
4896 4896                  proc_t *p;
4897 4897  
4898 4898                  /*
4899 4899                   * Find next entry.  Skip processes not visible where
4900 4900                   * this /proc was mounted.
4901 4901                   */
4902 4902                  mutex_enter(&pidlock);
4903 4903                  while (n < v.v_proc &&
4904 4904                      ((p = pid_entry(n)) == NULL || p->p_stat == SIDL ||
4905 4905                      (zoneid != GLOBAL_ZONEID && p->p_zone->zone_id != zoneid) ||
4906 4906                      secpolicy_basic_procinfo(CRED(), p, curproc) != 0))
4907 4907                          n++;
4908 4908  
4909 4909                  /*
4910 4910                   * Stop when entire proc table has been examined.
4911 4911                   */
4912 4912                  if (n >= v.v_proc) {
4913 4913                          mutex_exit(&pidlock);
4914 4914                          eof = 1;
4915 4915                          break;
4916 4916                  }
4917 4917  
4918 4918                  ASSERT(p->p_stat != 0);
4919 4919                  pid = p->p_pid;
4920 4920                  pslot = p->p_slot;
4921 4921                  mutex_exit(&pidlock);
4922 4922                  error = gfs_readdir_emitn(&gstate, uiop, n,
4923 4923                      pmkino(0, pslot, PR_PIDDIR), pid);
4924 4924                  if (error)
4925 4925                          break;
4926 4926          }
4927 4927  
4928 4928          return (gfs_readdir_fini(&gstate, error, eofp, eof));
4929 4929  }
4930 4930  
4931 4931  /* ARGSUSED */
4932 4932  static int
4933 4933  pr_readdir_piddir(prnode_t *pnp, uio_t *uiop, int *eofp)
4934 4934  {
4935 4935          int zombie = ((pnp->pr_pcommon->prc_flags & PRC_DESTROY) != 0);
4936 4936          prdirent_t dirent;
4937 4937          prdirent_t *dirp;
4938 4938          offset_t off;
4939 4939          int error;
4940 4940  
4941 4941          ASSERT(pnp->pr_type == PR_PIDDIR);
4942 4942  
4943 4943          if (uiop->uio_offset < 0 ||
4944 4944              uiop->uio_offset % sizeof (prdirent_t) != 0 ||
4945 4945              uiop->uio_resid < sizeof (prdirent_t))
4946 4946                  return (EINVAL);
4947 4947          if (pnp->pr_pcommon->prc_proc == NULL)
4948 4948                  return (ENOENT);
4949 4949          if (uiop->uio_offset >= sizeof (piddir))
4950 4950                  goto out;
4951 4951  
4952 4952          /*
4953 4953           * Loop until user's request is satisfied, omitting some
4954 4954           * files along the way if the process is a zombie.
4955 4955           */
4956 4956          for (dirp = &piddir[uiop->uio_offset / sizeof (prdirent_t)];
4957 4957              uiop->uio_resid >= sizeof (prdirent_t) &&
4958 4958              dirp < &piddir[NPIDDIRFILES+2];
4959 4959              uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
4960 4960                  off = uiop->uio_offset;
4961 4961                  if (zombie) {
4962 4962                          switch (dirp->d_ino) {
4963 4963                          case PR_PIDDIR:
4964 4964                          case PR_PROCDIR:
4965 4965                          case PR_PSINFO:
4966 4966                          case PR_USAGE:
4967 4967                          case PR_ARGV:
4968 4968                                  break;
4969 4969                          default:
4970 4970                                  continue;
4971 4971                          }
4972 4972                  }
4973 4973                  bcopy(dirp, &dirent, sizeof (prdirent_t));
4974 4974                  if (dirent.d_ino == PR_PROCDIR)
4975 4975                          dirent.d_ino = PRROOTINO;
4976 4976                  else
4977 4977                          dirent.d_ino = pmkino(0, pnp->pr_pcommon->prc_slot,
4978 4978                              dirent.d_ino);
4979 4979                  if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
4980 4980                      UIO_READ, uiop)) != 0)
4981 4981                          return (error);
4982 4982          }
4983 4983  out:
4984 4984          if (eofp)
4985 4985                  *eofp = (uiop->uio_offset >= sizeof (piddir));
4986 4986          return (0);
4987 4987  }
4988 4988  
4989 4989  static void
4990 4990  rebuild_objdir(struct as *as)
4991 4991  {
4992 4992          struct seg *seg;
4993 4993          vnode_t *vp;
4994 4994          vattr_t vattr;
4995 4995          vnode_t **dir;
4996 4996          ulong_t nalloc;
4997 4997          ulong_t nentries;
4998 4998          int i, j;
4999 4999          ulong_t nold, nnew;
5000 5000  
5001 5001          ASSERT(AS_WRITE_HELD(as));
5002 5002  
5003 5003          if (as->a_updatedir == 0 && as->a_objectdir != NULL)
5004 5004                  return;
5005 5005          as->a_updatedir = 0;
5006 5006  
5007 5007          if ((nalloc = avl_numnodes(&as->a_segtree)) == 0 ||
5008 5008              (seg = AS_SEGFIRST(as)) == NULL)    /* can't happen? */
5009 5009                  return;
5010 5010  
5011 5011          /*
5012 5012           * Allocate space for the new object directory.
5013 5013           * (This is usually about two times too many entries.)
5014 5014           */
5015 5015          nalloc = (nalloc + 0xf) & ~0xf;         /* multiple of 16 */
5016 5016          dir = kmem_zalloc(nalloc * sizeof (vnode_t *), KM_SLEEP);
5017 5017  
5018 5018          /* fill in the new directory with desired entries */
5019 5019          nentries = 0;
5020 5020          do {
5021 5021                  vattr.va_mask = AT_FSID|AT_NODEID;
5022 5022                  if (seg->s_ops == &segvn_ops &&
5023 5023                      SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
5024 5024                      vp != NULL && vp->v_type == VREG &&
5025 5025                      VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
5026 5026                          for (i = 0; i < nentries; i++)
5027 5027                                  if (vp == dir[i])
5028 5028                                          break;
5029 5029                          if (i == nentries) {
5030 5030                                  ASSERT(nentries < nalloc);
5031 5031                                  dir[nentries++] = vp;
5032 5032                          }
5033 5033                  }
5034 5034          } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
5035 5035  
5036 5036          if (as->a_objectdir == NULL) {  /* first time */
5037 5037                  as->a_objectdir = dir;
5038 5038                  as->a_sizedir = nalloc;
5039 5039                  return;
5040 5040          }
5041 5041  
5042 5042          /*
5043 5043           * Null out all of the defunct entries in the old directory.
5044 5044           */
5045 5045          nold = 0;
5046 5046          nnew = nentries;
5047 5047          for (i = 0; i < as->a_sizedir; i++) {
5048 5048                  if ((vp = as->a_objectdir[i]) != NULL) {
5049 5049                          for (j = 0; j < nentries; j++) {
5050 5050                                  if (vp == dir[j]) {
5051 5051                                          dir[j] = NULL;
5052 5052                                          nnew--;
5053 5053                                          break;
5054 5054                                  }
5055 5055                          }
5056 5056                          if (j == nentries)
5057 5057                                  as->a_objectdir[i] = NULL;
5058 5058                          else
5059 5059                                  nold++;
5060 5060                  }
5061 5061          }
5062 5062  
5063 5063          if (nold + nnew > as->a_sizedir) {
5064 5064                  /*
5065 5065                   * Reallocate the old directory to have enough
5066 5066                   * space for the old and new entries combined.
5067 5067                   * Round up to the next multiple of 16.
5068 5068                   */
5069 5069                  ulong_t newsize = (nold + nnew + 0xf) & ~0xf;
5070 5070                  vnode_t **newdir = kmem_zalloc(newsize * sizeof (vnode_t *),
5071 5071                      KM_SLEEP);
5072 5072                  bcopy(as->a_objectdir, newdir,
5073 5073                      as->a_sizedir * sizeof (vnode_t *));
5074 5074                  kmem_free(as->a_objectdir, as->a_sizedir * sizeof (vnode_t *));
5075 5075                  as->a_objectdir = newdir;
5076 5076                  as->a_sizedir = newsize;
5077 5077          }
5078 5078  
5079 5079          /*
5080 5080           * Move all new entries to the old directory and
5081 5081           * deallocate the space used by the new directory.
5082 5082           */
5083 5083          if (nnew) {
5084 5084                  for (i = 0, j = 0; i < nentries; i++) {
5085 5085                          if ((vp = dir[i]) == NULL)
5086 5086                                  continue;
5087 5087                          for (; j < as->a_sizedir; j++) {
5088 5088                                  if (as->a_objectdir[j] != NULL)
5089 5089                                          continue;
5090 5090                                  as->a_objectdir[j++] = vp;
5091 5091                                  break;
5092 5092                          }
5093 5093                  }
5094 5094          }
5095 5095          kmem_free(dir, nalloc * sizeof (vnode_t *));
5096 5096  }
5097 5097  
5098 5098  /*
5099 5099   * Return the vnode from a slot in the process's object directory.
5100 5100   * The caller must have locked the process's address space.
5101 5101   * The only caller is below, in pr_readdir_objectdir().
5102 5102   */
5103 5103  static vnode_t *
5104 5104  obj_entry(struct as *as, int slot)
5105 5105  {
5106 5106          ASSERT(AS_LOCK_HELD(as));
5107 5107          if (as->a_objectdir == NULL)
5108 5108                  return (NULL);
5109 5109          ASSERT(slot < as->a_sizedir);
5110 5110          return (as->a_objectdir[slot]);
5111 5111  }
5112 5112  
5113 5113  /* ARGSUSED */
5114 5114  static int
5115 5115  pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5116 5116  {
5117 5117          gfs_readdir_state_t gstate;
5118 5118          int error, eof = 0;
5119 5119          offset_t n;
5120 5120          int pslot;
5121 5121          size_t objdirsize;
5122 5122          proc_t *p;
5123 5123          struct as *as;
5124 5124          vnode_t *vp;
5125 5125  
5126 5126          ASSERT(pnp->pr_type == PR_OBJECTDIR);
5127 5127  
5128 5128          if ((error = prlock(pnp, ZNO)) != 0)
5129 5129                  return (error);
5130 5130          p = pnp->pr_common->prc_proc;
5131 5131          pslot = p->p_slot;
5132 5132  
5133 5133          /*
5134 5134           * We drop p_lock before grabbing the address space lock
5135 5135           * in order to avoid a deadlock with the clock thread.
5136 5136           * The process will not disappear and its address space
5137 5137           * will not change because it is marked P_PR_LOCK.
5138 5138           */
5139 5139          mutex_exit(&p->p_lock);
5140 5140  
5141 5141          if ((error = gfs_readdir_init(&gstate, 64, PRSDSIZE, uiop,
5142 5142              pmkino(0, pslot, PR_PIDDIR),
5143 5143              pmkino(0, pslot, PR_OBJECTDIR), 0)) != 0) {
5144 5144                  mutex_enter(&p->p_lock);
5145 5145                  prunlock(pnp);
5146 5146                  return (error);
5147 5147          }
5148 5148  
5149 5149          if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5150 5150                  as = NULL;
5151 5151                  objdirsize = 0;
5152 5152          }
5153 5153  
5154 5154          /*
5155 5155           * Loop until user's request is satisfied or until
5156 5156           * all mapped objects have been examined. Cannot hold
5157 5157           * the address space lock for the following call as
5158 5158           * gfs_readdir_pred() utimately causes a call to uiomove().
5159 5159           */
5160 5160          while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5161 5161                  vattr_t vattr;
5162 5162                  char str[64];
5163 5163  
5164 5164                  /*
5165 5165                   * Set the correct size of the directory just
5166 5166                   * in case the process has changed it's address
5167 5167                   * space via mmap/munmap calls.
5168 5168                   */
5169 5169                  if (as != NULL) {
5170 5170                          AS_LOCK_ENTER(as, RW_WRITER);
5171 5171                          if (as->a_updatedir)
5172 5172                                  rebuild_objdir(as);
5173 5173                          objdirsize = as->a_sizedir;
5174 5174                  }
5175 5175  
5176 5176                  /*
5177 5177                   * Find next object.
5178 5178                   */
5179 5179                  vattr.va_mask = AT_FSID | AT_NODEID;
5180 5180                  while (n < objdirsize && (((vp = obj_entry(as, n)) == NULL) ||
5181 5181                      (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL)
5182 5182                      != 0))) {
5183 5183                          vattr.va_mask = AT_FSID | AT_NODEID;
5184 5184                          n++;
5185 5185                  }
5186 5186  
5187 5187                  if (as != NULL)
5188 5188                          AS_LOCK_EXIT(as);
5189 5189  
5190 5190                  /*
5191 5191                   * Stop when all objects have been reported.
5192 5192                   */
5193 5193                  if (n >= objdirsize) {
5194 5194                          eof = 1;
5195 5195                          break;
5196 5196                  }
5197 5197  
5198 5198                  if (vp == p->p_exec)
5199 5199                          (void) strcpy(str, "a.out");
5200 5200                  else
5201 5201                          pr_object_name(str, vp, &vattr);
5202 5202  
5203 5203                  error = gfs_readdir_emit(&gstate, uiop, n, vattr.va_nodeid,
5204 5204                      str, 0);
5205 5205  
5206 5206                  if (error)
5207 5207                          break;
5208 5208          }
5209 5209  
5210 5210          mutex_enter(&p->p_lock);
5211 5211          prunlock(pnp);
5212 5212  
5213 5213          return (gfs_readdir_fini(&gstate, error, eofp, eof));
5214 5214  }
5215 5215  
5216 5216  /* ARGSUSED */
5217 5217  static int
5218 5218  pr_readdir_lwpdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5219 5219  {
5220 5220          gfs_readdir_state_t gstate;
5221 5221          int error, eof = 0;
5222 5222          offset_t tslot;
5223 5223          proc_t *p;
5224 5224          int pslot;
5225 5225          lwpdir_t *lwpdir;
5226 5226          int lwpdirsize;
5227 5227  
5228 5228          ASSERT(pnp->pr_type == PR_LWPDIR);
5229 5229  
5230 5230          p = pr_p_lock(pnp);
5231 5231          mutex_exit(&pr_pidlock);
5232 5232          if (p == NULL)
5233 5233                  return (ENOENT);
5234 5234          ASSERT(p == pnp->pr_common->prc_proc);
5235 5235          pslot = p->p_slot;
5236 5236          lwpdir = p->p_lwpdir;
5237 5237          lwpdirsize = p->p_lwpdir_sz;
5238 5238  
5239 5239          /*
5240 5240           * Drop p->p_lock so we can safely do uiomove().
5241 5241           * The lwp directory will not change because
5242 5242           * we have the process locked with P_PR_LOCK.
5243 5243           */
5244 5244          mutex_exit(&p->p_lock);
5245 5245  
5246 5246  
5247 5247          if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5248 5248              pmkino(0, pslot, PR_PIDDIR),
5249 5249              pmkino(0, pslot, PR_LWPDIR), 0)) != 0) {
5250 5250                  mutex_enter(&p->p_lock);
5251 5251                  prunlock(pnp);
5252 5252                  return (error);
5253 5253          }
5254 5254  
5255 5255          /*
5256 5256           * Loop until user's request is satisfied or until all lwps
5257 5257           * have been examined.
5258 5258           */
5259 5259          while ((error = gfs_readdir_pred(&gstate, uiop, &tslot)) == 0) {
5260 5260                  lwpent_t *lep;
5261 5261                  uint_t tid;
5262 5262  
5263 5263                  /*
5264 5264                   * Find next LWP.
5265 5265                   */
5266 5266                  while (tslot < lwpdirsize &&
5267 5267                      ((lep = lwpdir[tslot].ld_entry) == NULL))
5268 5268                          tslot++;
5269 5269                  /*
5270 5270                   * Stop when all lwps have been reported.
5271 5271                   */
5272 5272                  if (tslot >= lwpdirsize) {
5273 5273                          eof = 1;
5274 5274                          break;
5275 5275                  }
5276 5276  
5277 5277                  tid = lep->le_lwpid;
5278 5278                  error = gfs_readdir_emitn(&gstate, uiop, tslot,
5279 5279                      pmkino(tslot, pslot, PR_LWPIDDIR), tid);
5280 5280                  if (error)
5281 5281                          break;
5282 5282          }
5283 5283  
5284 5284          mutex_enter(&p->p_lock);
5285 5285          prunlock(pnp);
5286 5286  
5287 5287          return (gfs_readdir_fini(&gstate, error, eofp, eof));
5288 5288  }
5289 5289  
5290 5290  /* ARGSUSED */
5291 5291  static int
5292 5292  pr_readdir_lwpiddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5293 5293  {
5294 5294          prcommon_t *pcp = pnp->pr_common;
5295 5295          int zombie = ((pcp->prc_flags & PRC_DESTROY) != 0);
5296 5296          prdirent_t dirent;
5297 5297          prdirent_t *dirp;
5298 5298          offset_t off;
5299 5299          int error;
5300 5300          int pslot;
5301 5301          int tslot;
5302 5302  
5303 5303          ASSERT(pnp->pr_type == PR_LWPIDDIR);
5304 5304  
5305 5305          if (uiop->uio_offset < 0 ||
5306 5306              uiop->uio_offset % sizeof (prdirent_t) != 0 ||
5307 5307              uiop->uio_resid < sizeof (prdirent_t))
5308 5308                  return (EINVAL);
5309 5309          if (pcp->prc_proc == NULL || pcp->prc_tslot == -1)
5310 5310                  return (ENOENT);
5311 5311          if (uiop->uio_offset >= sizeof (lwpiddir))
5312 5312                  goto out;
5313 5313  
5314 5314          /*
5315 5315           * Loop until user's request is satisfied, omitting some files
5316 5316           * along the way if the lwp is a zombie and also depending
5317 5317           * on the data model of the process.
5318 5318           */
5319 5319          pslot = pcp->prc_slot;
5320 5320          tslot = pcp->prc_tslot;
5321 5321          for (dirp = &lwpiddir[uiop->uio_offset / sizeof (prdirent_t)];
5322 5322              uiop->uio_resid >= sizeof (prdirent_t) &&
5323 5323              dirp < &lwpiddir[NLWPIDDIRFILES+2];
5324 5324              uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
5325 5325                  off = uiop->uio_offset;
5326 5326                  if (zombie) {
5327 5327                          switch (dirp->d_ino) {
5328 5328                          case PR_LWPIDDIR:
5329 5329                          case PR_LWPDIR:
5330 5330                          case PR_LWPSINFO:
5331 5331                                  break;
5332 5332                          default:
5333 5333                                  continue;
5334 5334                          }
5335 5335                  }
5336 5336  #if defined(__sparc)
5337 5337                  /* the asrs file exists only for sparc v9 _LP64 processes */
5338 5338                  if (dirp->d_ino == PR_ASRS &&
5339 5339                      pcp->prc_datamodel != DATAMODEL_LP64)
5340 5340                          continue;
5341 5341  #endif
5342 5342                  bcopy(dirp, &dirent, sizeof (prdirent_t));
5343 5343                  if (dirent.d_ino == PR_LWPDIR)
5344 5344                          dirent.d_ino = pmkino(0, pslot, dirp->d_ino);
5345 5345                  else
5346 5346                          dirent.d_ino = pmkino(tslot, pslot, dirp->d_ino);
5347 5347                  if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
5348 5348                      UIO_READ, uiop)) != 0)
5349 5349                          return (error);
5350 5350          }
5351 5351  out:
5352 5352          if (eofp)
5353 5353                  *eofp = (uiop->uio_offset >= sizeof (lwpiddir));
5354 5354          return (0);
5355 5355  }
5356 5356  
5357 5357  /* ARGSUSED */
5358 5358  static int
5359 5359  pr_readdir_fddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5360 5360  {
5361 5361          gfs_readdir_state_t gstate;
5362 5362          int error, eof = 0;
5363 5363          offset_t n;
5364 5364          proc_t *p;
5365 5365          int pslot;
5366 5366          int fddirsize;
5367 5367          uf_info_t *fip;
5368 5368  
5369 5369          ASSERT(pnp->pr_type == PR_FDDIR);
5370 5370  
5371 5371          if ((error = prlock(pnp, ZNO)) != 0)
5372 5372                  return (error);
5373 5373          p = pnp->pr_common->prc_proc;
5374 5374          pslot = p->p_slot;
5375 5375          fip = P_FINFO(p);
5376 5376          mutex_exit(&p->p_lock);
5377 5377  
5378 5378          if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5379 5379              pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_FDDIR), 0)) != 0) {
5380 5380                  mutex_enter(&p->p_lock);
5381 5381                  prunlock(pnp);
5382 5382                  return (error);
5383 5383          }
5384 5384  
5385 5385          mutex_enter(&fip->fi_lock);
5386 5386          if ((p->p_flag & SSYS) || p->p_as == &kas)
5387 5387                  fddirsize = 0;
5388 5388          else
5389 5389                  fddirsize = fip->fi_nfiles;
5390 5390  
5391 5391          /*
5392 5392           * Loop until user's request is satisfied or until
5393 5393           * all file descriptors have been examined.
5394 5394           */
5395 5395          while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5396 5396                  /*
5397 5397                   * Find next fd.
5398 5398                   */
5399 5399                  while (n < fddirsize && fip->fi_list[n].uf_file == NULL)
5400 5400                          n++;
5401 5401                  /*
5402 5402                   * Stop when all fds have been reported.
5403 5403                   */
5404 5404                  if (n >= fddirsize) {
5405 5405                          eof = 1;
5406 5406                          break;
5407 5407                  }
5408 5408  
5409 5409                  error = gfs_readdir_emitn(&gstate, uiop, n,
5410 5410                      pmkino(n, pslot, PR_FD), n);
5411 5411                  if (error)
5412 5412                          break;
5413 5413          }
5414 5414  
5415 5415          mutex_exit(&fip->fi_lock);
5416 5416          mutex_enter(&p->p_lock);
5417 5417          prunlock(pnp);
5418 5418  
5419 5419          return (gfs_readdir_fini(&gstate, error, eofp, eof));
5420 5420  }
5421 5421  
5422 5422  /* ARGSUSED */
5423 5423  static int
5424 5424  pr_readdir_pathdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5425 5425  {
5426 5426          longlong_t bp[DIRENT64_RECLEN(64) / sizeof (longlong_t)];
5427 5427          dirent64_t *dirent = (dirent64_t *)bp;
5428 5428          int reclen;
5429 5429          ssize_t oresid;
5430 5430          offset_t off, idx;
5431 5431          int error = 0;
5432 5432          proc_t *p;
5433 5433          int fd, obj;
5434 5434          int pslot;
5435 5435          int fddirsize;
5436 5436          uf_info_t *fip;
5437 5437          struct as *as = NULL;
5438 5438          size_t objdirsize;
5439 5439          vattr_t vattr;
5440 5440          vnode_t *vp;
5441 5441  
5442 5442          ASSERT(pnp->pr_type == PR_PATHDIR);
5443 5443  
5444 5444          if (uiop->uio_offset < 0 ||
5445 5445              uiop->uio_resid <= 0 ||
5446 5446              (uiop->uio_offset % PRSDSIZE) != 0)
5447 5447                  return (EINVAL);
5448 5448          oresid = uiop->uio_resid;
5449 5449          bzero(bp, sizeof (bp));
5450 5450  
5451 5451          if ((error = prlock(pnp, ZNO)) != 0)
5452 5452                  return (error);
5453 5453          p = pnp->pr_common->prc_proc;
5454 5454          fip = P_FINFO(p);
5455 5455          pslot = p->p_slot;
5456 5456          mutex_exit(&p->p_lock);
5457 5457  
5458 5458          if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5459 5459                  as = NULL;
5460 5460                  objdirsize = 0;
5461 5461          } else {
5462 5462                  AS_LOCK_ENTER(as, RW_WRITER);
5463 5463                  if (as->a_updatedir)
5464 5464                          rebuild_objdir(as);
5465 5465                  objdirsize = as->a_sizedir;
5466 5466                  AS_LOCK_EXIT(as);
5467 5467                  as = NULL;
5468 5468          }
5469 5469  
5470 5470          mutex_enter(&fip->fi_lock);
5471 5471          if ((p->p_flag & SSYS) || p->p_as == &kas)
5472 5472                  fddirsize = 0;
5473 5473          else
5474 5474                  fddirsize = fip->fi_nfiles;
5475 5475  
5476 5476          for (; uiop->uio_resid > 0; uiop->uio_offset = off + PRSDSIZE) {
5477 5477                  /*
5478 5478                   * There are 4 special files in the path directory: ".", "..",
5479 5479                   * "root", and "cwd".  We handle those specially here.
5480 5480                   */
5481 5481                  off = uiop->uio_offset;
5482 5482                  idx = off / PRSDSIZE;
5483 5483                  if (off == 0) {                         /* "." */
5484 5484                          dirent->d_ino = pmkino(0, pslot, PR_PATHDIR);
5485 5485                          dirent->d_name[0] = '.';
5486 5486                          dirent->d_name[1] = '\0';
5487 5487                          reclen = DIRENT64_RECLEN(1);
5488 5488                  } else if (idx == 1) {                  /* ".." */
5489 5489                          dirent->d_ino = pmkino(0, pslot, PR_PIDDIR);
5490 5490                          dirent->d_name[0] = '.';
5491 5491                          dirent->d_name[1] = '.';
5492 5492                          dirent->d_name[2] = '\0';
5493 5493                          reclen = DIRENT64_RECLEN(2);
5494 5494                  } else if (idx == 2) {                  /* "root" */
5495 5495                          dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5496 5496                          (void) strcpy(dirent->d_name, "root");
5497 5497                          reclen = DIRENT64_RECLEN(4);
5498 5498                  } else if (idx == 3) {                  /* "cwd" */
5499 5499                          dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5500 5500                          (void) strcpy(dirent->d_name, "cwd");
5501 5501                          reclen = DIRENT64_RECLEN(3);
5502 5502                  } else if (idx < 4 + fddirsize) {
5503 5503                          /*
5504 5504                           * In this case, we have one of the file descriptors.
5505 5505                           */
5506 5506                          fd = idx - 4;
5507 5507                          if (fip->fi_list[fd].uf_file == NULL)
5508 5508                                  continue;
5509 5509                          dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5510 5510                          (void) pr_u32tos(fd, dirent->d_name, PLNSIZ+1);
5511 5511                          reclen = DIRENT64_RECLEN(PLNSIZ);
5512 5512                  } else if (idx < 4 + fddirsize + objdirsize) {
5513 5513                          if (fip != NULL) {
5514 5514                                  mutex_exit(&fip->fi_lock);
5515 5515                                  fip = NULL;
5516 5516                          }
5517 5517  
5518 5518                          /*
5519 5519                           * We drop p_lock before grabbing the address space lock
5520 5520                           * in order to avoid a deadlock with the clock thread.
5521 5521                           * The process will not disappear and its address space
5522 5522                           * will not change because it is marked P_PR_LOCK.
5523 5523                           */
5524 5524                          if (as == NULL) {
5525 5525                                  as = p->p_as;
5526 5526                                  AS_LOCK_ENTER(as, RW_WRITER);
5527 5527                          }
5528 5528  
5529 5529                          if (as->a_updatedir) {
5530 5530                                  rebuild_objdir(as);
5531 5531                                  objdirsize = as->a_sizedir;
5532 5532                          }
5533 5533  
5534 5534                          obj = idx - 4 - fddirsize;
5535 5535                          if ((vp = obj_entry(as, obj)) == NULL)
5536 5536                                  continue;
5537 5537                          vattr.va_mask = AT_FSID|AT_NODEID;
5538 5538                          if (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) != 0)
5539 5539                                  continue;
5540 5540                          if (vp == p->p_exec)
5541 5541                                  (void) strcpy(dirent->d_name, "a.out");
5542 5542                          else
5543 5543                                  pr_object_name(dirent->d_name, vp, &vattr);
5544 5544                          dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5545 5545                          reclen = DIRENT64_RECLEN(strlen(dirent->d_name));
5546 5546                  } else {
5547 5547                          break;
5548 5548                  }
5549 5549  
5550 5550                  dirent->d_off = uiop->uio_offset + PRSDSIZE;
5551 5551                  dirent->d_reclen = (ushort_t)reclen;
5552 5552                  if (reclen > uiop->uio_resid) {
5553 5553                          /*
5554 5554                           * Error if no entries have been returned yet.
5555 5555                           */
5556 5556                          if (uiop->uio_resid == oresid)
5557 5557                                  error = EINVAL;
5558 5558                          break;
5559 5559                  }
5560 5560                  /*
5561 5561                   * Drop the address space lock to do the uiomove().
5562 5562                   */
5563 5563                  if (as != NULL)
5564 5564                          AS_LOCK_EXIT(as);
5565 5565  
5566 5566                  error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop);
5567 5567                  if (as != NULL)
5568 5568                          AS_LOCK_ENTER(as, RW_WRITER);
5569 5569  
5570 5570                  if (error)
5571 5571                          break;
5572 5572          }
5573 5573  
5574 5574          if (error == 0 && eofp)
5575 5575                  *eofp = (uiop->uio_offset >= (fddirsize + 2) * PRSDSIZE);
5576 5576  
5577 5577          if (fip != NULL)
5578 5578                  mutex_exit(&fip->fi_lock);
5579 5579          if (as != NULL)
5580 5580                  AS_LOCK_EXIT(as);
5581 5581          mutex_enter(&p->p_lock);
5582 5582          prunlock(pnp);
5583 5583          return (error);
5584 5584  }
5585 5585  
5586 5586  static int
5587 5587  pr_readdir_tmpldir(prnode_t *pnp, uio_t *uiop, int *eofp)
5588 5588  {
5589 5589          proc_t *p;
5590 5590          int pslot, tslot;
5591 5591          gfs_readdir_state_t gstate;
5592 5592          int error, eof = 0;
5593 5593          offset_t n;
5594 5594  
5595 5595          ASSERT(pnp->pr_type == PR_TMPLDIR);
5596 5596  
5597 5597          if ((error = prlock(pnp, ZNO)) != 0)
5598 5598                  return (error);
5599 5599          p = pnp->pr_common->prc_proc;
5600 5600          pslot = pnp->pr_common->prc_slot;
5601 5601          tslot = pnp->pr_common->prc_tslot;
5602 5602          mutex_exit(&p->p_lock);
5603 5603  
5604 5604          if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5605 5605              pmkino(tslot, pslot, PR_LWPDIR),
5606 5606              pmkino(tslot, pslot, PR_TMPLDIR), 0)) != 0) {
5607 5607                  mutex_enter(&p->p_lock);
5608 5608                  prunlock(pnp);
5609 5609                  return (error);
5610 5610          }
5611 5611  
5612 5612          while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5613 5613                  /*
5614 5614                   * Check for an active template.  Reading a directory's
5615 5615                   * contents is already racy, so we don't bother taking
5616 5616                   * any locks.
5617 5617                   */
5618 5618                  while (n < ct_ntypes &&
5619 5619                      pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[n] == NULL)
5620 5620                          n++;
5621 5621                  /*
5622 5622                   * Stop when all types have been reported.
5623 5623                   */
5624 5624                  if (n >= ct_ntypes) {
5625 5625                          eof = 1;
5626 5626                          break;
5627 5627                  }
5628 5628                  /*
5629 5629                   * The pmkino invocation below will need to be updated
5630 5630                   * when we create our fifth contract type.
5631 5631                   */
5632 5632                  ASSERT(ct_ntypes <= 4);
5633 5633                  error = gfs_readdir_emit(&gstate, uiop, n,
5634 5634                      pmkino((tslot << 2) | n, pslot, PR_TMPL),
5635 5635                      ct_types[n]->ct_type_name, 0);
5636 5636                  if (error)
5637 5637                          break;
5638 5638          }
5639 5639  
5640 5640          mutex_enter(&p->p_lock);
5641 5641          prunlock(pnp);
5642 5642  
5643 5643          return (gfs_readdir_fini(&gstate, error, eofp, eof));
5644 5644  }
5645 5645  
5646 5646  static int
5647 5647  pr_readdir_ctdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5648 5648  {
5649 5649          proc_t *p;
5650 5650          int pslot;
5651 5651          gfs_readdir_state_t gstate;
5652 5652          int error, eof = 0;
5653 5653          offset_t n;
5654 5654          uint64_t zid;
5655 5655  
5656 5656          ASSERT(pnp->pr_type == PR_CTDIR);
5657 5657  
5658 5658          if ((error = prlock(pnp, ZNO)) != 0)
5659 5659                  return (error);
5660 5660          p = pnp->pr_common->prc_proc;
5661 5661          pslot = p->p_slot;
5662 5662          mutex_exit(&p->p_lock);
5663 5663  
5664 5664          if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5665 5665              pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_CTDIR), 0)) != 0) {
5666 5666                  mutex_enter(&p->p_lock);
5667 5667                  prunlock(pnp);
5668 5668                  return (error);
5669 5669          }
5670 5670  
5671 5671          zid = VTOZONE(pnp->pr_vnode)->zone_uniqid;
5672 5672          while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5673 5673                  id_t next = contract_plookup(p, n, zid);
5674 5674                  if (next == -1) {
5675 5675                          eof = 1;
5676 5676                          break;
5677 5677                  }
5678 5678                  error = gfs_readdir_emitn(&gstate, uiop, next,
5679 5679                      pmkino(next, pslot, PR_CT), next);
5680 5680                  if (error)
5681 5681                          break;
5682 5682          }
5683 5683  
5684 5684          mutex_enter(&p->p_lock);
5685 5685          prunlock(pnp);
5686 5686  
5687 5687          return (gfs_readdir_fini(&gstate, error, eofp, eof));
5688 5688  }
5689 5689  
5690 5690  /* ARGSUSED */
5691 5691  static int
5692 5692  prfsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
5693 5693  {
5694 5694          return (0);
5695 5695  }
5696 5696  
5697 5697  /*
5698 5698   * Utility: remove a /proc vnode from a linked list, threaded through pr_next.
5699 5699   */
5700 5700  static void
5701 5701  pr_list_unlink(vnode_t *pvp, vnode_t **listp)
5702 5702  {
5703 5703          vnode_t *vp;
5704 5704          prnode_t *pnp;
5705 5705  
5706 5706          while ((vp = *listp) != NULL) {
5707 5707                  pnp = VTOP(vp);
5708 5708                  if (vp == pvp) {
5709 5709                          *listp = pnp->pr_next;
5710 5710                          pnp->pr_next = NULL;
5711 5711                          break;
5712 5712                  }
5713 5713                  listp = &pnp->pr_next;
5714 5714          }
5715 5715  }
5716 5716  
5717 5717  /* ARGSUSED */
5718 5718  static void
5719 5719  prinactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
5720 5720  {
5721 5721          prnode_t *pnp = VTOP(vp);
5722 5722          prnodetype_t type = pnp->pr_type;
5723 5723          proc_t *p;
5724 5724          vnode_t *dp;
5725 5725          vnode_t *ovp = NULL;
5726 5726          prnode_t *opnp = NULL;
5727 5727  
5728 5728          switch (type) {
5729 5729          case PR_OBJECT:
5730 5730          case PR_FD:
5731 5731          case PR_SELF:
5732 5732          case PR_PATH:
5733 5733                  /* These are not linked into the usual lists */
5734 5734                  ASSERT(vp->v_count == 1);
5735 5735                  if ((dp = pnp->pr_parent) != NULL)
5736 5736                          VN_RELE(dp);
5737 5737                  prfreenode(pnp);
5738 5738                  return;
5739 5739          default:
5740 5740                  break;
5741 5741          }
5742 5742  
5743 5743          mutex_enter(&pr_pidlock);
5744 5744          if (pnp->pr_pcommon == NULL)
5745 5745                  p = NULL;
5746 5746          else if ((p = pnp->pr_pcommon->prc_proc) != NULL)
5747 5747                  mutex_enter(&p->p_lock);
5748 5748          mutex_enter(&vp->v_lock);
5749 5749  
5750 5750          if (type == PR_PROCDIR || vp->v_count > 1) {
5751 5751                  vp->v_count--;
5752 5752                  mutex_exit(&vp->v_lock);
5753 5753                  if (p != NULL)
5754 5754                          mutex_exit(&p->p_lock);
5755 5755                  mutex_exit(&pr_pidlock);
5756 5756                  return;
5757 5757          }
5758 5758  
5759 5759          if ((dp = pnp->pr_parent) != NULL) {
5760 5760                  prnode_t *dpnp;
5761 5761  
5762 5762                  switch (type) {
5763 5763                  case PR_PIDFILE:
5764 5764                  case PR_LWPIDFILE:
5765 5765                  case PR_OPAGEDATA:
5766 5766                          break;
5767 5767                  default:
5768 5768                          dpnp = VTOP(dp);
5769 5769                          mutex_enter(&dpnp->pr_mutex);
5770 5770                          if (dpnp->pr_files != NULL &&
5771 5771                              dpnp->pr_files[pnp->pr_index] == vp)
5772 5772                                  dpnp->pr_files[pnp->pr_index] = NULL;
5773 5773                          mutex_exit(&dpnp->pr_mutex);
5774 5774                          break;
5775 5775                  }
5776 5776                  pnp->pr_parent = NULL;
5777 5777          }
5778 5778  
5779 5779          ASSERT(vp->v_count == 1);
5780 5780  
5781 5781          /*
5782 5782           * If we allocated an old /proc/pid node, free it too.
5783 5783           */
5784 5784          if (pnp->pr_pidfile != NULL) {
5785 5785                  ASSERT(type == PR_PIDDIR);
5786 5786                  ovp = pnp->pr_pidfile;
5787 5787                  opnp = VTOP(ovp);
5788 5788                  ASSERT(opnp->pr_type == PR_PIDFILE);
5789 5789                  pnp->pr_pidfile = NULL;
5790 5790          }
5791 5791  
5792 5792          mutex_exit(&pr_pidlock);
5793 5793  
5794 5794          if (p != NULL) {
5795 5795                  /*
5796 5796                   * Remove the vnodes from the lists of
5797 5797                   * /proc vnodes for the process.
5798 5798                   */
5799 5799                  int slot;
5800 5800  
5801 5801                  switch (type) {
5802 5802                  case PR_PIDDIR:
5803 5803                          pr_list_unlink(vp, &p->p_trace);
5804 5804                          break;
5805 5805                  case PR_LWPIDDIR:
5806 5806                          if ((slot = pnp->pr_common->prc_tslot) != -1) {
5807 5807                                  lwpent_t *lep = p->p_lwpdir[slot].ld_entry;
5808 5808                                  pr_list_unlink(vp, &lep->le_trace);
5809 5809                          }
5810 5810                          break;
5811 5811                  default:
5812 5812                          pr_list_unlink(vp, &p->p_plist);
5813 5813                          break;
5814 5814                  }
5815 5815                  if (ovp != NULL)
5816 5816                          pr_list_unlink(ovp, &p->p_plist);
5817 5817                  mutex_exit(&p->p_lock);
5818 5818          }
5819 5819  
5820 5820          mutex_exit(&vp->v_lock);
5821 5821  
5822 5822          if (type == PR_CT && pnp->pr_contract != NULL) {
5823 5823                  contract_rele(pnp->pr_contract);
5824 5824                  pnp->pr_contract = NULL;
5825 5825          }
5826 5826  
5827 5827          if (opnp != NULL)
5828 5828                  prfreenode(opnp);
5829 5829          prfreenode(pnp);
5830 5830          if (dp != NULL) {
5831 5831                  VN_RELE(dp);
5832 5832          }
5833 5833  }
5834 5834  
5835 5835  /* ARGSUSED */
5836 5836  static int
5837 5837  prseek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
5838 5838  {
5839 5839          return (0);
5840 5840  }
5841 5841  
5842 5842  /*
5843 5843   * We use the p_execdir member of proc_t to expand the %d token in core file
5844 5844   * paths (the directory path for the executable that dumped core; see
5845 5845   * coreadm(1M) for details). We'd like gcore(1) to be able to expand %d in
5846 5846   * the same way as core dumping from the kernel, but there's no convenient
5847 5847   * and comprehensible way to export the path name for p_execdir. To solve
5848 5848   * this, we try to find the actual path to the executable that was used. In
5849 5849   * pr_lookup_pathdir(), we mark the a.out path name vnode with the PR_AOUT
5850 5850   * flag, and use that here to indicate that more work is needed beyond the
5851 5851   * call to vnodetopath().
5852 5852   */
5853 5853  static int
5854 5854  prreadlink_lookup(prnode_t *pnp, char *buf, size_t size, cred_t *cr)
5855 5855  {
5856 5856          proc_t *p;
5857 5857          vnode_t *vp, *execvp, *vrootp;
5858 5858          int ret;
5859 5859          size_t len;
5860 5860          dirent64_t *dp;
5861 5861          size_t dlen = DIRENT64_RECLEN(MAXPATHLEN);
5862 5862          char *dbuf;
5863 5863  
5864 5864          p = curproc;
5865 5865          mutex_enter(&p->p_lock);
5866 5866          if ((vrootp = PTOU(p)->u_rdir) == NULL)
5867 5867                  vrootp = rootdir;
5868 5868          VN_HOLD(vrootp);
5869 5869          mutex_exit(&p->p_lock);
5870 5870  
5871 5871          ret = vnodetopath(vrootp, pnp->pr_realvp, buf, size, cr);
5872 5872  
5873 5873          /*
5874 5874           * If PR_AOUT isn't set, then we looked up the path for the vnode;
5875 5875           * otherwise, we looked up the path for (what we believe to be) the
5876 5876           * containing directory.
5877 5877           */
5878 5878          if ((pnp->pr_flags & PR_AOUT) == 0) {
5879 5879                  VN_RELE(vrootp);
5880 5880                  return (ret);
5881 5881          }
5882 5882  
5883 5883          /*
5884 5884           * Fail if there's a problem locking the process. This will only
5885 5885           * occur if the process is changing so the information we would
5886 5886           * report would already be invalid.
5887 5887           */
5888 5888          if (prlock(pnp, ZNO) != 0) {
5889 5889                  VN_RELE(vrootp);
5890 5890                  return (EIO);
5891 5891          }
5892 5892  
5893 5893          p = pnp->pr_common->prc_proc;
5894 5894          mutex_exit(&p->p_lock);
5895 5895  
5896 5896          execvp = p->p_exec;
5897 5897          VN_HOLD(execvp);
5898 5898  
5899 5899          /*
5900 5900           * If our initial lookup of the directory failed, fall back to
5901 5901           * the path name information for p_exec.
5902 5902           */
5903 5903          if (ret != 0) {
5904 5904                  mutex_enter(&p->p_lock);
5905 5905                  prunlock(pnp);
5906 5906                  ret = vnodetopath(vrootp, execvp, buf, size, cr);
5907 5907                  VN_RELE(execvp);
5908 5908                  VN_RELE(vrootp);
5909 5909                  return (ret);
5910 5910          }
5911 5911  
5912 5912          len = strlen(buf);
5913 5913  
5914 5914          /*
5915 5915           * We use u_comm as a guess for the last component of the full
5916 5916           * executable path name. If there isn't going to be enough space
5917 5917           * we fall back to using the p_exec so that we can have _an_
5918 5918           * answer even if it's not perfect.
5919 5919           */
5920 5920          if (strlen(PTOU(p)->u_comm) + len + 1 < size) {
5921 5921                  buf[len] = '/';
5922 5922                  (void) strcpy(buf + len + 1, PTOU(p)->u_comm);
5923 5923                  mutex_enter(&p->p_lock);
5924 5924                  prunlock(pnp);
5925 5925  
5926 5926                  /*
5927 5927                   * Do a forward lookup of our u_comm guess.
5928 5928                   */
5929 5929                  if (lookupnameat(buf + len + 1, UIO_SYSSPACE, FOLLOW, NULLVPP,
5930 5930                      &vp, pnp->pr_realvp) == 0) {
5931 5931                          if (vn_compare(vp, execvp)) {
5932 5932                                  VN_RELE(vp);
5933 5933                                  VN_RELE(execvp);
5934 5934                                  VN_RELE(vrootp);
5935 5935                                  return (0);
5936 5936                          }
5937 5937  
5938 5938                          VN_RELE(vp);
5939 5939                  }
5940 5940          } else {
5941 5941                  mutex_enter(&p->p_lock);
5942 5942                  prunlock(pnp);
5943 5943          }
5944 5944  
5945 5945          dbuf = kmem_alloc(dlen, KM_SLEEP);
5946 5946  
5947 5947          /*
5948 5948           * Try to find a matching vnode by iterating through the directory's
5949 5949           * entries. If that fails, fall back to the path information for
5950 5950           * p_exec.
5951 5951           */
5952 5952          if ((ret = dirfindvp(vrootp, pnp->pr_realvp, execvp, cr, dbuf,
5953 5953              dlen, &dp)) == 0 && strlen(dp->d_name) + len + 1 < size) {
5954 5954                  buf[len] = '/';
5955 5955                  (void) strcpy(buf + len + 1, dp->d_name);
5956 5956          } else {
5957 5957                  ret = vnodetopath(vrootp, execvp, buf, size, cr);
5958 5958          }
5959 5959  
5960 5960          kmem_free(dbuf, dlen);
5961 5961          VN_RELE(execvp);
5962 5962          VN_RELE(vrootp);
5963 5963  
5964 5964          return (ret);
5965 5965  }
5966 5966  
5967 5967  /* ARGSUSED */
5968 5968  static int
5969 5969  prreadlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ctp)
5970 5970  {
5971 5971          prnode_t *pnp = VTOP(vp);
5972 5972          char *buf;
5973 5973          int ret = EINVAL;
5974 5974          char idbuf[16];
5975 5975          int length, rlength;
5976 5976          contract_t *ct;
5977 5977  
5978 5978          switch (pnp->pr_type) {
5979 5979          case PR_SELF:
5980 5980                  (void) snprintf(idbuf, sizeof (idbuf), "%d", curproc->p_pid);
5981 5981                  ret = uiomove(idbuf, strlen(idbuf), UIO_READ, uiop);
5982 5982                  break;
5983 5983          case PR_OBJECT:
5984 5984          case PR_FD:
5985 5985          case PR_CURDIR:
5986 5986          case PR_ROOTDIR:
5987 5987                  if (pnp->pr_realvp->v_type == VDIR)
5988 5988                          ret = 0;
5989 5989                  break;
5990 5990          case PR_PATH:
5991 5991                  buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
5992 5992  
5993 5993                  if ((ret = prreadlink_lookup(pnp, buf, MAXPATHLEN, cr)) == 0)
5994 5994                          ret = uiomove(buf, strlen(buf), UIO_READ, uiop);
5995 5995  
5996 5996                  kmem_free(buf, MAXPATHLEN);
5997 5997                  break;
5998 5998          case PR_CT:
5999 5999                  ASSERT(pnp->pr_contract != NULL);
6000 6000                  ct = pnp->pr_contract;
6001 6001                  length = sizeof (CTFS_ROOT "//") + sizeof (idbuf) +
6002 6002                      strlen(ct->ct_type->ct_type_name);
6003 6003                  buf = kmem_alloc(length, KM_SLEEP);
6004 6004                  rlength = snprintf(buf, length, CTFS_ROOT "/%s/%d",
6005 6005                      ct->ct_type->ct_type_name, ct->ct_id);
6006 6006                  ASSERT(rlength < length);
6007 6007                  ret = uiomove(buf, rlength, UIO_READ, uiop);
6008 6008                  kmem_free(buf, length);
6009 6009                  break;
6010 6010          default:
6011 6011                  break;
6012 6012          }
6013 6013  
6014 6014          return (ret);
6015 6015  }
6016 6016  
6017 6017  /*ARGSUSED2*/
6018 6018  static int
6019 6019  prcmp(vnode_t *vp1, vnode_t *vp2, caller_context_t *ct)
6020 6020  {
6021 6021          prnode_t *pp1, *pp2;
6022 6022  
6023 6023          if (vp1 == vp2)
6024 6024                  return (1);
6025 6025  
6026 6026          if (!vn_matchops(vp1, prvnodeops) || !vn_matchops(vp2, prvnodeops))
6027 6027                  return (0);
6028 6028  
6029 6029          pp1 = VTOP(vp1);
6030 6030          pp2 = VTOP(vp2);
6031 6031  
6032 6032          if (pp1->pr_type != pp2->pr_type)
6033 6033                  return (0);
6034 6034          if (pp1->pr_type == PR_PROCDIR)
6035 6035                  return (1);
6036 6036          if (pp1->pr_ino || pp2->pr_ino)
6037 6037                  return (pp2->pr_ino == pp1->pr_ino);
6038 6038  
6039 6039          if (pp1->pr_common == NULL || pp2->pr_common == NULL)
6040 6040                  return (0);
6041 6041  
6042 6042          return (pp1->pr_common->prc_slot == pp2->pr_common->prc_slot &&
6043 6043              pp1->pr_common->prc_tslot == pp2->pr_common->prc_tslot);
6044 6044  }
6045 6045  
6046 6046  static int
6047 6047  prrealvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
6048 6048  {
6049 6049          vnode_t *rvp;
6050 6050  
6051 6051          if ((rvp = VTOP(vp)->pr_realvp) != NULL) {
6052 6052                  vp = rvp;
6053 6053                  if (VOP_REALVP(vp, &rvp, ct) == 0)
6054 6054                          vp = rvp;
6055 6055          }
6056 6056  
6057 6057          *vpp = vp;
6058 6058          return (0);
6059 6059  }
6060 6060  
6061 6061  /*
6062 6062   * Return the answer requested to poll().
6063 6063   * POLLIN, POLLRDNORM, and POLLOUT are recognized as in fs_poll().
6064 6064   * In addition, these have special meaning for /proc files:
6065 6065   *      POLLPRI         process or lwp stopped on an event of interest
6066 6066   *      POLLERR         /proc file descriptor is invalid
6067 6067   *      POLLHUP         process or lwp has terminated
6068 6068   */
6069 6069  /*ARGSUSED5*/
6070 6070  static int
6071 6071  prpoll(vnode_t *vp, short events, int anyyet, short *reventsp,
6072 6072          pollhead_t **phpp, caller_context_t *ct)
6073 6073  {
6074 6074          prnode_t *pnp = VTOP(vp);
6075 6075          prcommon_t *pcp = pnp->pr_common;
6076 6076          pollhead_t *php = &pcp->prc_pollhead;
6077 6077          proc_t *p;
6078 6078          short revents;
6079 6079          int error;
6080 6080          int lockstate;
6081 6081  
6082 6082          ASSERT(pnp->pr_type < PR_NFILES);
6083 6083  
6084 6084          /*
6085 6085           * Support for old /proc interface.
6086 6086           */
6087 6087          if (pnp->pr_pidfile != NULL) {
6088 6088                  vp = pnp->pr_pidfile;
6089 6089                  pnp = VTOP(vp);
6090 6090                  ASSERT(pnp->pr_type == PR_PIDFILE);
6091 6091                  ASSERT(pnp->pr_common == pcp);
6092 6092          }
6093 6093  
6094 6094          *reventsp = revents = 0;
6095 6095          *phpp = (pollhead_t *)NULL;
6096 6096  
6097 6097          if (vp->v_type == VDIR) {
6098 6098                  *reventsp |= POLLNVAL;
6099 6099                  return (0);
6100 6100          }
6101 6101  
6102 6102          /* avoid deadlock with prnotify() */
6103 6103          if (pollunlock(&lockstate) != 0) {
6104 6104                  *reventsp = POLLNVAL;
6105 6105                  return (0);
6106 6106          }
6107 6107  
6108 6108          if ((error = prlock(pnp, ZNO)) != 0) {
6109 6109                  pollrelock(lockstate);
6110 6110                  switch (error) {
6111 6111                  case ENOENT:            /* process or lwp died */
6112 6112                          *reventsp = POLLHUP;
6113 6113                          error = 0;
6114 6114                          break;
6115 6115                  case EAGAIN:            /* invalidated */
6116 6116                          *reventsp = POLLERR;
6117 6117                          error = 0;
6118 6118                          break;
6119 6119                  }
6120 6120                  return (error);
6121 6121          }
6122 6122  
6123 6123          /*
6124 6124           * We have the process marked locked (P_PR_LOCK) and we are holding
6125 6125           * its p->p_lock.  We want to unmark the process but retain
6126 6126           * exclusive control w.r.t. other /proc controlling processes
6127 6127           * before reacquiring the polling locks.
6128 6128           *
6129 6129           * prunmark() does this for us.  It unmarks the process
6130 6130           * but retains p->p_lock so we still have exclusive control.
6131 6131           * We will drop p->p_lock at the end to relinquish control.
6132 6132           *
6133 6133           * We cannot call prunlock() at the end to relinquish control
6134 6134           * because prunlock(), like prunmark(), may drop and reacquire
6135 6135           * p->p_lock and that would lead to a lock order violation
6136 6136           * w.r.t. the polling locks we are about to reacquire.
6137 6137           */
6138 6138          p = pcp->prc_proc;
6139 6139          ASSERT(p != NULL);
6140 6140          prunmark(p);
6141 6141  
6142 6142          pollrelock(lockstate);          /* reacquire dropped poll locks */
6143 6143  
6144 6144          if ((p->p_flag & SSYS) || p->p_as == &kas)
6145 6145                  revents = POLLNVAL;
6146 6146          else {
6147 6147                  short ev;
6148 6148  
6149 6149                  if ((ev = (events & (POLLIN|POLLRDNORM))) != 0)
6150 6150                          revents |= ev;
6151 6151                  /*
6152 6152                   * POLLWRNORM (same as POLLOUT) really should not be
6153 6153                   * used to indicate that the process or lwp stopped.
6154 6154                   * However, USL chose to use POLLWRNORM rather than
6155 6155                   * POLLPRI to indicate this, so we just accept either
6156 6156                   * requested event to indicate stopped.  (grr...)
6157 6157                   */
6158 6158                  if ((ev = (events & (POLLPRI|POLLOUT|POLLWRNORM))) != 0) {
6159 6159                          kthread_t *t;
6160 6160  
6161 6161                          if (pcp->prc_flags & PRC_LWP) {
6162 6162                                  t = pcp->prc_thread;
6163 6163                                  ASSERT(t != NULL);
6164 6164                                  thread_lock(t);
6165 6165                          } else {
6166 6166                                  t = prchoose(p);        /* returns locked t */
6167 6167                                  ASSERT(t != NULL);
6168 6168                          }
6169 6169  
6170 6170                          if (ISTOPPED(t) || VSTOPPED(t))
6171 6171                                  revents |= ev;
6172 6172                          thread_unlock(t);
6173 6173                  }
6174 6174          }
6175 6175  
6176 6176          *reventsp = revents;
6177 6177          if ((!anyyet && revents == 0) || (events & POLLET)) {
6178 6178                  /*
6179 6179                   * Arrange to wake up the polling lwp when
6180 6180                   * the target process/lwp stops or terminates
6181 6181                   * or when the file descriptor becomes invalid.
6182 6182                   */
6183 6183                  pcp->prc_flags |= PRC_POLL;
6184 6184                  *phpp = php;
6185 6185          }
6186 6186          mutex_exit(&p->p_lock);
6187 6187          return (0);
6188 6188  }
6189 6189  
6190 6190  /* in prioctl.c */
6191 6191  extern int prioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
6192 6192          caller_context_t *);
6193 6193  
6194 6194  /*
6195 6195   * /proc vnode operations vector
6196 6196   */
6197 6197  const fs_operation_def_t pr_vnodeops_template[] = {
6198 6198          VOPNAME_OPEN,           { .vop_open = propen },
6199 6199          VOPNAME_CLOSE,          { .vop_close = prclose },
6200 6200          VOPNAME_READ,           { .vop_read = prread },
6201 6201          VOPNAME_WRITE,          { .vop_write = prwrite },
6202 6202          VOPNAME_IOCTL,          { .vop_ioctl = prioctl },
6203 6203          VOPNAME_GETATTR,        { .vop_getattr = prgetattr },
6204 6204          VOPNAME_ACCESS,         { .vop_access = praccess },
6205 6205          VOPNAME_LOOKUP,         { .vop_lookup = prlookup },
6206 6206          VOPNAME_CREATE,         { .vop_create = prcreate },
6207 6207          VOPNAME_READDIR,        { .vop_readdir = prreaddir },
6208 6208          VOPNAME_READLINK,       { .vop_readlink = prreadlink },
6209 6209          VOPNAME_FSYNC,          { .vop_fsync = prfsync },
6210 6210          VOPNAME_INACTIVE,       { .vop_inactive = prinactive },
6211 6211          VOPNAME_SEEK,           { .vop_seek = prseek },
6212 6212          VOPNAME_CMP,            { .vop_cmp = prcmp },
6213 6213          VOPNAME_FRLOCK,         { .error = fs_error },
6214 6214          VOPNAME_REALVP,         { .vop_realvp = prrealvp },
6215 6215          VOPNAME_POLL,           { .vop_poll = prpoll },
6216 6216          VOPNAME_DISPOSE,        { .error = fs_error },
6217 6217          VOPNAME_SHRLOCK,        { .error = fs_error },
6218 6218          NULL,                   NULL
6219 6219  };
  
    | 
      ↓ open down ↓ | 
    6219 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX