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.


  37 #include <fcntl.h>
  38 #include <string.h>
  39 #include <strings.h>
  40 #include <memory.h>
  41 #include <errno.h>
  42 #include <dirent.h>
  43 #include <limits.h>
  44 #include <signal.h>
  45 #include <atomic.h>
  46 #include <zone.h>
  47 #include <sys/types.h>
  48 #include <sys/uio.h>
  49 #include <sys/stat.h>
  50 #include <sys/resource.h>
  51 #include <sys/param.h>
  52 #include <sys/stack.h>
  53 #include <sys/fault.h>
  54 #include <sys/syscall.h>
  55 #include <sys/sysmacros.h>
  56 #include <sys/systeminfo.h>

  57 
  58 #include "libproc.h"
  59 #include "Pcontrol.h"
  60 #include "Putil.h"
  61 #include "P32ton.h"
  62 
  63 int     _libproc_debug;         /* set non-zero to enable debugging printfs */
  64 int     _libproc_no_qsort;      /* set non-zero to inhibit sorting */
  65                                 /* of symbol tables */
  66 int     _libproc_incore_elf;    /* only use in-core elf data */
  67 
  68 sigset_t blockable_sigs;        /* signals to block when we need to be safe */
  69 static  int     minfd;  /* minimum file descriptor returned by dupfd(fd, 0) */
  70 char    procfs_path[PATH_MAX] = "/proc";
  71 
  72 /*
  73  * Function prototypes for static routines in this module.
  74  */
  75 static  void    deadcheck(struct ps_prochandle *);
  76 static  void    restore_tracing_flags(struct ps_prochandle *);


 159                         free(auxv);
 160                 } else {
 161                         auxv[naux].a_type = AT_NULL;
 162                         auxv[naux].a_un.a_val = 0L;
 163 
 164                         *auxvp = auxv;
 165                         *nauxp = (int)naux;
 166                 }
 167         }
 168 
 169         (void) close(fd);
 170 }
 171 
 172 /*ARGSUSED*/
 173 static int
 174 Pcred_live(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data)
 175 {
 176         return (proc_get_cred(P->pid, pcrp, ngroups));
 177 }
 178 







 179 /*ARGSUSED*/
 180 static int
 181 Ppriv_live(struct ps_prochandle *P, prpriv_t **pprv, void *data)
 182 {
 183         prpriv_t *pp;
 184 
 185         pp = proc_get_priv(P->pid);
 186         if (pp == NULL) {
 187                 return (-1);
 188         }
 189 
 190         *pprv = pp;
 191         return (0);
 192 }
 193 
 194 /*ARGSUSED*/
 195 static const psinfo_t *
 196 Ppsinfo_live(struct ps_prochandle *P, psinfo_t *psinfo, void *data)
 197 {
 198         if (proc_get_psinfo(P->pid, psinfo) == -1)


 309 Pldt_live(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data)
 310 {
 311         return (proc_get_ldt(P->pid, pldt, nldt));
 312 }
 313 #endif
 314 
 315 static const ps_ops_t P_live_ops = {
 316         .pop_pread      = Pread_live,
 317         .pop_pwrite     = Pwrite_live,
 318         .pop_read_maps  = Pread_maps_live,
 319         .pop_read_aux   = Pread_aux_live,
 320         .pop_cred       = Pcred_live,
 321         .pop_priv       = Ppriv_live,
 322         .pop_psinfo     = Ppsinfo_live,
 323         .pop_lstatus    = Plstatus_live,
 324         .pop_lpsinfo    = Plpsinfo_live,
 325         .pop_platform   = Pplatform_live,
 326         .pop_uname      = Puname_live,
 327         .pop_zonename   = Pzonename_live,
 328         .pop_execname   = Pexecname_live,

 329 #if defined(__i386) || defined(__amd64)
 330         .pop_ldt        = Pldt_live
 331 #endif
 332 };
 333 
 334 /*
 335  * This is the library's .init handler.
 336  */
 337 #pragma init(_libproc_init)
 338 void
 339 _libproc_init(void)
 340 {
 341         _libproc_debug = getenv("LIBPROC_DEBUG") != NULL;
 342         _libproc_no_qsort = getenv("LIBPROC_NO_QSORT") != NULL;
 343         _libproc_incore_elf = getenv("LIBPROC_INCORE_ELF") != NULL;
 344 
 345         (void) sigfillset(&blockable_sigs);
 346         (void) sigdelset(&blockable_sigs, SIGKILL);
 347         (void) sigdelset(&blockable_sigs, SIGSTOP);
 348 }


1276 }
1277 
1278 static void
1279 Pread_status(struct ps_prochandle *P)
1280 {
1281         P->ops.pop_status(P, &P->status, P->data);
1282 }
1283 
1284 /*
1285  * Fill in a pointer to a process credentials structure.  The ngroups parameter
1286  * is the number of supplementary group entries allocated in the caller's cred
1287  * structure.  It should equal zero or one unless extra space has been
1288  * allocated for the group list by the caller.
1289  */
1290 int
1291 Pcred(struct ps_prochandle *P, prcred_t *pcrp, int ngroups)
1292 {
1293         return (P->ops.pop_cred(P, pcrp, ngroups, P->data));
1294 }
1295 






















1296 static prheader_t *
1297 Plstatus(struct ps_prochandle *P)
1298 {
1299         return (P->ops.pop_lstatus(P, P->data));
1300 }
1301 
1302 static prheader_t *
1303 Plpsinfo(struct ps_prochandle *P)
1304 {
1305         return (P->ops.pop_lpsinfo(P, P->data));
1306 }
1307 
1308 
1309 #if defined(__i386) || defined(__amd64)
1310 /*
1311  * Fill in a pointer to a process LDT structure.
1312  * The caller provides a buffer of size 'nldt * sizeof (struct ssd)';
1313  * If pldt == NULL or nldt == 0, we return the number of existing LDT entries.
1314  * Otherwise we return the actual number of LDT entries fetched (<= nldt).
1315  */




  37 #include <fcntl.h>
  38 #include <string.h>
  39 #include <strings.h>
  40 #include <memory.h>
  41 #include <errno.h>
  42 #include <dirent.h>
  43 #include <limits.h>
  44 #include <signal.h>
  45 #include <atomic.h>
  46 #include <zone.h>
  47 #include <sys/types.h>
  48 #include <sys/uio.h>
  49 #include <sys/stat.h>
  50 #include <sys/resource.h>
  51 #include <sys/param.h>
  52 #include <sys/stack.h>
  53 #include <sys/fault.h>
  54 #include <sys/syscall.h>
  55 #include <sys/sysmacros.h>
  56 #include <sys/systeminfo.h>
  57 #include <sys/secflags.h>
  58 
  59 #include "libproc.h"
  60 #include "Pcontrol.h"
  61 #include "Putil.h"
  62 #include "P32ton.h"
  63 
  64 int     _libproc_debug;         /* set non-zero to enable debugging printfs */
  65 int     _libproc_no_qsort;      /* set non-zero to inhibit sorting */
  66                                 /* of symbol tables */
  67 int     _libproc_incore_elf;    /* only use in-core elf data */
  68 
  69 sigset_t blockable_sigs;        /* signals to block when we need to be safe */
  70 static  int     minfd;  /* minimum file descriptor returned by dupfd(fd, 0) */
  71 char    procfs_path[PATH_MAX] = "/proc";
  72 
  73 /*
  74  * Function prototypes for static routines in this module.
  75  */
  76 static  void    deadcheck(struct ps_prochandle *);
  77 static  void    restore_tracing_flags(struct ps_prochandle *);


 160                         free(auxv);
 161                 } else {
 162                         auxv[naux].a_type = AT_NULL;
 163                         auxv[naux].a_un.a_val = 0L;
 164 
 165                         *auxvp = auxv;
 166                         *nauxp = (int)naux;
 167                 }
 168         }
 169 
 170         (void) close(fd);
 171 }
 172 
 173 /*ARGSUSED*/
 174 static int
 175 Pcred_live(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data)
 176 {
 177         return (proc_get_cred(P->pid, pcrp, ngroups));
 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 
 187 /*ARGSUSED*/
 188 static int
 189 Ppriv_live(struct ps_prochandle *P, prpriv_t **pprv, void *data)
 190 {
 191         prpriv_t *pp;
 192 
 193         pp = proc_get_priv(P->pid);
 194         if (pp == NULL) {
 195                 return (-1);
 196         }
 197 
 198         *pprv = pp;
 199         return (0);
 200 }
 201 
 202 /*ARGSUSED*/
 203 static const psinfo_t *
 204 Ppsinfo_live(struct ps_prochandle *P, psinfo_t *psinfo, void *data)
 205 {
 206         if (proc_get_psinfo(P->pid, psinfo) == -1)


 317 Pldt_live(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data)
 318 {
 319         return (proc_get_ldt(P->pid, pldt, nldt));
 320 }
 321 #endif
 322 
 323 static const ps_ops_t P_live_ops = {
 324         .pop_pread      = Pread_live,
 325         .pop_pwrite     = Pwrite_live,
 326         .pop_read_maps  = Pread_maps_live,
 327         .pop_read_aux   = Pread_aux_live,
 328         .pop_cred       = Pcred_live,
 329         .pop_priv       = Ppriv_live,
 330         .pop_psinfo     = Ppsinfo_live,
 331         .pop_lstatus    = Plstatus_live,
 332         .pop_lpsinfo    = Plpsinfo_live,
 333         .pop_platform   = Pplatform_live,
 334         .pop_uname      = Puname_live,
 335         .pop_zonename   = Pzonename_live,
 336         .pop_execname   = Pexecname_live,
 337         .pop_secflags   = Psecflags_live,
 338 #if defined(__i386) || defined(__amd64)
 339         .pop_ldt        = Pldt_live
 340 #endif
 341 };
 342 
 343 /*
 344  * This is the library's .init handler.
 345  */
 346 #pragma init(_libproc_init)
 347 void
 348 _libproc_init(void)
 349 {
 350         _libproc_debug = getenv("LIBPROC_DEBUG") != NULL;
 351         _libproc_no_qsort = getenv("LIBPROC_NO_QSORT") != NULL;
 352         _libproc_incore_elf = getenv("LIBPROC_INCORE_ELF") != NULL;
 353 
 354         (void) sigfillset(&blockable_sigs);
 355         (void) sigdelset(&blockable_sigs, SIGKILL);
 356         (void) sigdelset(&blockable_sigs, SIGSTOP);
 357 }


1285 }
1286 
1287 static void
1288 Pread_status(struct ps_prochandle *P)
1289 {
1290         P->ops.pop_status(P, &P->status, P->data);
1291 }
1292 
1293 /*
1294  * Fill in a pointer to a process credentials structure.  The ngroups parameter
1295  * is the number of supplementary group entries allocated in the caller's cred
1296  * structure.  It should equal zero or one unless extra space has been
1297  * allocated for the group list by the caller.
1298  */
1299 int
1300 Pcred(struct ps_prochandle *P, prcred_t *pcrp, int ngroups)
1301 {
1302         return (P->ops.pop_cred(P, pcrp, ngroups, P->data));
1303 }
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 
1327 static prheader_t *
1328 Plstatus(struct ps_prochandle *P)
1329 {
1330         return (P->ops.pop_lstatus(P, P->data));
1331 }
1332 
1333 static prheader_t *
1334 Plpsinfo(struct ps_prochandle *P)
1335 {
1336         return (P->ops.pop_lpsinfo(P, P->data));
1337 }
1338 
1339 
1340 #if defined(__i386) || defined(__amd64)
1341 /*
1342  * Fill in a pointer to a process LDT structure.
1343  * The caller provides a buffer of size 'nldt * sizeof (struct ssd)';
1344  * If pldt == NULL or nldt == 0, we return the number of existing LDT entries.
1345  * Otherwise we return the actual number of LDT entries fetched (<= nldt).
1346  */