Print this page
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libproc/common/Pcontrol.c
          +++ new/usr/src/lib/libproc/common/Pcontrol.c
↓ open down ↓ 46 lines elided ↑ open up ↑
  47   47  #include <sys/types.h>
  48   48  #include <sys/uio.h>
  49   49  #include <sys/stat.h>
  50   50  #include <sys/resource.h>
  51   51  #include <sys/param.h>
  52   52  #include <sys/stack.h>
  53   53  #include <sys/fault.h>
  54   54  #include <sys/syscall.h>
  55   55  #include <sys/sysmacros.h>
  56   56  #include <sys/systeminfo.h>
       57 +#include <sys/secflags.h>
  57   58  
  58   59  #include "libproc.h"
  59   60  #include "Pcontrol.h"
  60   61  #include "Putil.h"
  61   62  #include "P32ton.h"
  62   63  
  63   64  int     _libproc_debug;         /* set non-zero to enable debugging printfs */
  64   65  int     _libproc_no_qsort;      /* set non-zero to inhibit sorting */
  65   66                                  /* of symbol tables */
  66   67  int     _libproc_incore_elf;    /* only use in-core elf data */
↓ open down ↓ 102 lines elided ↑ open up ↑
 169  170          (void) close(fd);
 170  171  }
 171  172  
 172  173  /*ARGSUSED*/
 173  174  static int
 174  175  Pcred_live(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data)
 175  176  {
 176  177          return (proc_get_cred(P->pid, pcrp, ngroups));
 177  178  }
 178  179  
      180 +/* ARGSUSED */
      181 +static int
      182 +Psecflags_live(struct ps_prochandle *P, prsecflags_t **psf, void *data)
      183 +{
      184 +        return (proc_get_secflags(P->pid, psf));
      185 +}
      186 +
 179  187  /*ARGSUSED*/
 180  188  static int
 181  189  Ppriv_live(struct ps_prochandle *P, prpriv_t **pprv, void *data)
 182  190  {
 183  191          prpriv_t *pp;
 184  192  
 185  193          pp = proc_get_priv(P->pid);
 186  194          if (pp == NULL) {
 187  195                  return (-1);
 188  196          }
↓ open down ↓ 130 lines elided ↑ open up ↑
 319  327          .pop_read_aux   = Pread_aux_live,
 320  328          .pop_cred       = Pcred_live,
 321  329          .pop_priv       = Ppriv_live,
 322  330          .pop_psinfo     = Ppsinfo_live,
 323  331          .pop_lstatus    = Plstatus_live,
 324  332          .pop_lpsinfo    = Plpsinfo_live,
 325  333          .pop_platform   = Pplatform_live,
 326  334          .pop_uname      = Puname_live,
 327  335          .pop_zonename   = Pzonename_live,
 328  336          .pop_execname   = Pexecname_live,
      337 +        .pop_secflags   = Psecflags_live,
 329  338  #if defined(__i386) || defined(__amd64)
 330  339          .pop_ldt        = Pldt_live
 331  340  #endif
 332  341  };
 333  342  
 334  343  /*
 335  344   * This is the library's .init handler.
 336  345   */
 337  346  #pragma init(_libproc_init)
 338  347  void
↓ open down ↓ 72 lines elided ↑ open up ↑
 411  420  }
 412  421  
 413  422  /*
 414  423   * Create a new controlled process.
 415  424   * Leave it stopped on successful exit from exec() or execve().
 416  425   * Return an opaque pointer to its process control structure.
 417  426   * Return NULL if process cannot be created (fork()/exec() not successful).
 418  427   */
 419  428  struct ps_prochandle *
 420  429  Pxcreate(const char *file,      /* executable file name */
 421      -        char *const *argv,      /* argument vector */
 422      -        char *const *envp,      /* environment */
 423      -        int *perr,      /* pointer to error return code */
 424      -        char *path,     /* if non-null, holds exec path name on return */
 425      -        size_t len)     /* size of the path buffer */
      430 +    char *const *argv,          /* argument vector */
      431 +    char *const *envp,          /* environment */
      432 +    int *perr,                  /* pointer to error return code */
      433 +    char *path,         /* if non-null, holds exec path name on return */
      434 +    size_t len)                 /* size of the path buffer */
 426  435  {
 427  436          char execpath[PATH_MAX];
 428  437          char procname[PATH_MAX];
 429  438          struct ps_prochandle *P;
 430  439          pid_t pid;
 431  440          int fd;
 432  441          char *fname;
 433  442          int rc;
 434  443          int lasterrno = 0;
 435  444  
↓ open down ↓ 850 lines elided ↑ open up ↑
1286 1295   * is the number of supplementary group entries allocated in the caller's cred
1287 1296   * structure.  It should equal zero or one unless extra space has been
1288 1297   * allocated for the group list by the caller.
1289 1298   */
1290 1299  int
1291 1300  Pcred(struct ps_prochandle *P, prcred_t *pcrp, int ngroups)
1292 1301  {
1293 1302          return (P->ops.pop_cred(P, pcrp, ngroups, P->data));
1294 1303  }
1295 1304  
     1305 +/* Return an allocated prsecflags_t */
     1306 +int
     1307 +Psecflags(struct ps_prochandle *P, prsecflags_t **psf)
     1308 +{
     1309 +        int ret;
     1310 +
     1311 +        if ((ret = P->ops.pop_secflags(P, psf, P->data)) == 0) {
     1312 +                if ((*psf)->pr_version != PRSECFLAGS_VERSION_1) {
     1313 +                        errno = EINVAL;
     1314 +                        return (-1);
     1315 +                }
     1316 +        }
     1317 +
     1318 +        return (ret);
     1319 +}
     1320 +
     1321 +void
     1322 +Psecflags_free(prsecflags_t *psf)
     1323 +{
     1324 +        free(psf);
     1325 +}
     1326 +
1296 1327  static prheader_t *
1297 1328  Plstatus(struct ps_prochandle *P)
1298 1329  {
1299 1330          return (P->ops.pop_lstatus(P, P->data));
1300 1331  }
1301 1332  
1302 1333  static prheader_t *
1303 1334  Plpsinfo(struct ps_prochandle *P)
1304 1335  {
1305 1336          return (P->ops.pop_lpsinfo(P, P->data));
↓ open down ↓ 482 lines elided ↑ open up ↑
1788 1819  
1789 1820  /*
1790 1821   * Wait for the specified process to stop or terminate.
1791 1822   * Or, just get the current status (PCNULL).
1792 1823   * Or, direct it to stop and get the current status (PCDSTOP).
1793 1824   * If the agent LWP exists, do these things to the agent,
1794 1825   * else do these things to the process as a whole.
1795 1826   */
1796 1827  int
1797 1828  Pstopstatus(struct ps_prochandle *P,
1798      -        long request,           /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */
1799      -        uint_t msec)            /* if non-zero, timeout in milliseconds */
     1829 +    long request,               /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */
     1830 +    uint_t msec)                /* if non-zero, timeout in milliseconds */
1800 1831  {
1801 1832          int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
1802 1833          long ctl[3];
1803 1834          ssize_t rc;
1804 1835          int err;
1805 1836          int old_state = P->state;
1806 1837  
1807 1838          switch (P->state) {
1808 1839          case PS_RUN:
1809 1840                  break;
↓ open down ↓ 243 lines elided ↑ open up ↑
2053 2084                  return (-1);
2054 2085          }
2055 2086  
2056 2087          P->status.pr_lwp.pr_reg[regno] = reg;
2057 2088          P->flags |= SETREGS;    /* set registers before continuing */
2058 2089          return (0);
2059 2090  }
2060 2091  
2061 2092  int
2062 2093  Psetrun(struct ps_prochandle *P,
2063      -        int sig,        /* signal to pass to process */
2064      -        int flags)      /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */
     2094 +    int sig,    /* signal to pass to process */
     2095 +    int flags)  /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */
2065 2096  {
2066 2097          int ctlfd = (P->agentctlfd >= 0) ? P->agentctlfd : P->ctlfd;
2067 2098          int sbits = (PR_DSTOP | PR_ISTOP | PR_ASLEEP);
2068 2099  
2069 2100          long ctl[1 +                                    /* PCCFAULT     */
2070 2101              1 + sizeof (siginfo_t)/sizeof (long) +      /* PCSSIG/PCCSIG */
2071 2102              2 ];                                        /* PCRUN        */
2072 2103  
2073 2104          long *ctlp = ctl;
2074 2105          size_t size;
↓ open down ↓ 54 lines elided ↑ open up ↑
2129 2160                  }
2130 2161                  /* Otherwise pretend that the job-stopped process is running */
2131 2162          }
2132 2163  
2133 2164          P->state = PS_RUN;
2134 2165          return (0);
2135 2166  }
2136 2167  
2137 2168  ssize_t
2138 2169  Pread(struct ps_prochandle *P,
2139      -        void *buf,              /* caller's buffer */
2140      -        size_t nbyte,           /* number of bytes to read */
2141      -        uintptr_t address)      /* address in process */
     2170 +    void *buf,          /* caller's buffer */
     2171 +    size_t nbyte,       /* number of bytes to read */
     2172 +    uintptr_t address)  /* address in process */
2142 2173  {
2143 2174          return (P->ops.pop_pread(P, buf, nbyte, address, P->data));
2144 2175  }
2145 2176  
2146 2177  ssize_t
2147 2178  Pread_string(struct ps_prochandle *P,
2148      -        char *buf,              /* caller's buffer */
2149      -        size_t size,            /* upper limit on bytes to read */
2150      -        uintptr_t addr)         /* address in process */
     2179 +    char *buf,                  /* caller's buffer */
     2180 +    size_t size,                /* upper limit on bytes to read */
     2181 +    uintptr_t addr)             /* address in process */
2151 2182  {
2152 2183          enum { STRSZ = 40 };
2153 2184          char string[STRSZ + 1];
2154 2185          ssize_t leng = 0;
2155 2186          int nbyte;
2156 2187  
2157 2188          if (size < 2) {
2158 2189                  errno = EINVAL;
2159 2190                  return (-1);
2160 2191          }
↓ open down ↓ 15 lines elided ↑ open up ↑
2176 2207                          (void) strncpy(buf + leng, string, nbyte);
2177 2208                          leng += nbyte;
2178 2209                  }
2179 2210          }
2180 2211          buf[leng] = '\0';
2181 2212          return (leng);
2182 2213  }
2183 2214  
2184 2215  ssize_t
2185 2216  Pwrite(struct ps_prochandle *P,
2186      -        const void *buf,        /* caller's buffer */
2187      -        size_t nbyte,           /* number of bytes to write */
2188      -        uintptr_t address)      /* address in process */
     2217 +    const void *buf,    /* caller's buffer */
     2218 +    size_t nbyte,       /* number of bytes to write */
     2219 +    uintptr_t address)  /* address in process */
2189 2220  {
2190 2221          return (P->ops.pop_pwrite(P, buf, nbyte, address, P->data));
2191 2222  }
2192 2223  
2193 2224  int
2194 2225  Pclearsig(struct ps_prochandle *P)
2195 2226  {
2196 2227          int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
2197 2228          long ctl = PCCSIG;
2198 2229  
↓ open down ↓ 1186 lines elided ↑ open up ↑
3385 3416          L->lwp_flags &= ~(SETHOLD|SETREGS);
3386 3417  }
3387 3418  
3388 3419  /*
3389 3420   * Wait for the specified LWP to stop or terminate.
3390 3421   * Or, just get the current status (PCNULL).
3391 3422   * Or, direct it to stop and get the current status (PCDSTOP).
3392 3423   */
3393 3424  static int
3394 3425  Lstopstatus(struct ps_lwphandle *L,
3395      -        long request,           /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */
3396      -        uint_t msec)            /* if non-zero, timeout in milliseconds */
     3426 +    long request,               /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */
     3427 +    uint_t msec)                /* if non-zero, timeout in milliseconds */
3397 3428  {
3398 3429          int ctlfd = L->lwp_ctlfd;
3399 3430          long ctl[3];
3400 3431          ssize_t rc;
3401 3432          int err;
3402 3433  
3403 3434          switch (L->lwp_state) {
3404 3435          case PS_RUN:
3405 3436                  break;
3406 3437          case PS_STOP:
↓ open down ↓ 178 lines elided ↑ open up ↑
3585 3616                  return (-1);
3586 3617          }
3587 3618  
3588 3619          L->lwp_status.pr_reg[regno] = reg;
3589 3620          L->lwp_flags |= SETREGS;        /* set registers before continuing */
3590 3621          return (0);
3591 3622  }
3592 3623  
3593 3624  int
3594 3625  Lsetrun(struct ps_lwphandle *L,
3595      -        int sig,        /* signal to pass to LWP */
3596      -        int flags)      /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */
     3626 +    int sig,    /* signal to pass to LWP */
     3627 +    int flags)  /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */
3597 3628  {
3598 3629          int ctlfd = L->lwp_ctlfd;
3599 3630          int sbits = (PR_DSTOP | PR_ISTOP | PR_ASLEEP);
3600 3631  
3601 3632          long ctl[1 +                                    /* PCCFAULT     */
3602 3633              1 + sizeof (siginfo_t)/sizeof (long) +      /* PCSSIG/PCCSIG */
3603 3634              2 ];                                        /* PCRUN        */
3604 3635  
3605 3636          long *ctlp = ctl;
3606 3637          size_t size;
↓ open down ↓ 319 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX