Print this page
OS-5440 pfexec and the case of the missing error message
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>


  22 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2015, Joyent, Inc.
  25  */
  26 
  27 #include <sys/atomic.h>
  28 #include <sys/door.h>
  29 #include <sys/proc.h>
  30 #include <sys/cred_impl.h>
  31 #include <sys/policy.h>
  32 #include <sys/priv.h>
  33 #include <sys/klpd.h>
  34 #include <sys/errno.h>
  35 #include <sys/kmem.h>
  36 #include <sys/project.h>
  37 #include <sys/systm.h>
  38 #include <sys/sysmacros.h>
  39 #include <sys/pathname.h>
  40 #include <sys/varargs.h>
  41 #include <sys/zone.h>


  42 #include <netinet/in.h>
  43 
  44 #define ROUNDUP(a, n) (((a) + ((n) - 1)) & ~((n) - 1))
  45 
  46 static kmutex_t klpd_mutex;
  47 
  48 typedef struct klpd_reg {
  49         struct klpd_reg *klpd_next;
  50         struct klpd_reg **klpd_refp;
  51         door_handle_t   klpd_door;
  52         pid_t           klpd_door_pid;
  53         priv_set_t      klpd_pset;
  54         cred_t          *klpd_cred;
  55         int             klpd_indel;             /* Disabled */
  56         uint32_t        klpd_ref;
  57 } klpd_reg_t;
  58 
  59 
  60 /*
  61  * This data structure hangs off the credential of a process; the


 843     boolean_t *scrub)
 844 {
 845         klpd_reg_t *pfd;
 846         pfexec_arg_t *pap;
 847         pfexec_reply_t pr, *prp;
 848         door_arg_t da;
 849         int dres;
 850         cred_t *ncr = NULL;
 851         int err = EACCES;
 852         priv_set_t *iset;
 853         priv_set_t *lset;
 854         zone_t *myzone = crgetzone(CRED());
 855         size_t pasize = PFEXEC_ARG_SIZE(MAXPATHLEN);
 856 
 857         /* Find registration */
 858         mutex_enter(&myzone->zone_lock);
 859         if ((pfd = myzone->zone_pfexecd) != NULL)
 860                 klpd_hold(pfd);
 861         mutex_exit(&myzone->zone_lock);
 862 
 863         if (pfd == NULL)




 864                 return (0);

 865 
 866         if (pfd->klpd_door_pid == curproc->p_pid) {
 867                 klpd_rele(pfd);
 868                 return (0);
 869         }
 870 
 871         pap = kmem_zalloc(pasize, KM_SLEEP);
 872 
 873         if (get_path(pap->pfa_path, rpnp->pn_path, rpnp->pn_pathlen) == -1)
 874                 goto out1;
 875 
 876         pap->pfa_vers = PFEXEC_ARG_VERS;
 877         pap->pfa_call = PFEXEC_EXEC_ATTRS;
 878         pap->pfa_len = pasize;
 879         pap->pfa_uid = crgetruid(cr);
 880 
 881         da.data_ptr = (char *)pap;
 882         da.data_size = pap->pfa_len;
 883         da.desc_ptr = NULL;
 884         da.desc_num = 0;
 885         da.rbuf = (char *)&pr;
 886         da.rsize = sizeof (pr);
 887 
 888         while ((dres = door_ki_upcall(pfd->klpd_door, &da)) != 0) {
 889                 switch (dres) {
 890                 case EAGAIN:
 891                         delay(1);
 892                         continue;
 893                 case EINVAL:
 894                 case EBADF:
 895                         /* FALLTHROUGH */
 896                 case EINTR:
 897                         /* FALLTHROUGH */
 898                 default:



 899                         goto out;
 900                 }
 901         }
 902 
 903         prp = (pfexec_reply_t *)da.rbuf;
 904         /*
 905          * Check the size of the result and the alignment of the
 906          * privilege sets.
 907          */
 908         if (da.rsize < sizeof (pr) ||
 909             prp->pfr_ioff > da.rsize - sizeof (priv_set_t) ||
 910             prp->pfr_loff > da.rsize - sizeof (priv_set_t) ||
 911             (prp->pfr_loff & (sizeof (priv_chunk_t) - 1)) != 0 ||
 912             (prp->pfr_ioff & (sizeof (priv_chunk_t) - 1)) != 0)
 913                 goto out;
 914 
 915         /*
 916          * Get results:
 917          *      allow/allow with additional credentials/disallow[*]
 918          *




  22 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2015, Joyent, Inc.
  25  */
  26 
  27 #include <sys/atomic.h>
  28 #include <sys/door.h>
  29 #include <sys/proc.h>
  30 #include <sys/cred_impl.h>
  31 #include <sys/policy.h>
  32 #include <sys/priv.h>
  33 #include <sys/klpd.h>
  34 #include <sys/errno.h>
  35 #include <sys/kmem.h>
  36 #include <sys/project.h>
  37 #include <sys/systm.h>
  38 #include <sys/sysmacros.h>
  39 #include <sys/pathname.h>
  40 #include <sys/varargs.h>
  41 #include <sys/zone.h>
  42 #include <sys/cmn_err.h>
  43 #include <sys/sdt.h>
  44 #include <netinet/in.h>
  45 
  46 #define ROUNDUP(a, n) (((a) + ((n) - 1)) & ~((n) - 1))
  47 
  48 static kmutex_t klpd_mutex;
  49 
  50 typedef struct klpd_reg {
  51         struct klpd_reg *klpd_next;
  52         struct klpd_reg **klpd_refp;
  53         door_handle_t   klpd_door;
  54         pid_t           klpd_door_pid;
  55         priv_set_t      klpd_pset;
  56         cred_t          *klpd_cred;
  57         int             klpd_indel;             /* Disabled */
  58         uint32_t        klpd_ref;
  59 } klpd_reg_t;
  60 
  61 
  62 /*
  63  * This data structure hangs off the credential of a process; the


 845     boolean_t *scrub)
 846 {
 847         klpd_reg_t *pfd;
 848         pfexec_arg_t *pap;
 849         pfexec_reply_t pr, *prp;
 850         door_arg_t da;
 851         int dres;
 852         cred_t *ncr = NULL;
 853         int err = EACCES;
 854         priv_set_t *iset;
 855         priv_set_t *lset;
 856         zone_t *myzone = crgetzone(CRED());
 857         size_t pasize = PFEXEC_ARG_SIZE(MAXPATHLEN);
 858 
 859         /* Find registration */
 860         mutex_enter(&myzone->zone_lock);
 861         if ((pfd = myzone->zone_pfexecd) != NULL)
 862                 klpd_hold(pfd);
 863         mutex_exit(&myzone->zone_lock);
 864 
 865         if (pfd == NULL) {
 866                 DTRACE_PROBE2(pfexecd__not__running,
 867                     zone_t *, myzone, char *, rpnp->pn_path);
 868                 uprintf("pfexecd not running; pid %d privileges not "
 869                     "elevated\n", curproc->p_pid);
 870                 return (0);
 871         }
 872 
 873         if (pfd->klpd_door_pid == curproc->p_pid) {
 874                 klpd_rele(pfd);
 875                 return (0);
 876         }
 877 
 878         pap = kmem_zalloc(pasize, KM_SLEEP);
 879 
 880         if (get_path(pap->pfa_path, rpnp->pn_path, rpnp->pn_pathlen) == -1)
 881                 goto out1;
 882 
 883         pap->pfa_vers = PFEXEC_ARG_VERS;
 884         pap->pfa_call = PFEXEC_EXEC_ATTRS;
 885         pap->pfa_len = pasize;
 886         pap->pfa_uid = crgetruid(cr);
 887 
 888         da.data_ptr = (char *)pap;
 889         da.data_size = pap->pfa_len;
 890         da.desc_ptr = NULL;
 891         da.desc_num = 0;
 892         da.rbuf = (char *)&pr;
 893         da.rsize = sizeof (pr);
 894 
 895         while ((dres = door_ki_upcall(pfd->klpd_door, &da)) != 0) {
 896                 switch (dres) {
 897                 case EAGAIN:
 898                         delay(1);
 899                         continue;
 900                 case EINVAL:
 901                 case EBADF:
 902                         /* FALLTHROUGH */
 903                 case EINTR:
 904                         /* FALLTHROUGH */
 905                 default:
 906                         DTRACE_PROBE4(pfexecd__failure,
 907                             int, dres, zone_t *, myzone,
 908                             char *, rpnp->pn_path, klpd_reg_t *, pfd);
 909                         goto out;
 910                 }
 911         }
 912 
 913         prp = (pfexec_reply_t *)da.rbuf;
 914         /*
 915          * Check the size of the result and the alignment of the
 916          * privilege sets.
 917          */
 918         if (da.rsize < sizeof (pr) ||
 919             prp->pfr_ioff > da.rsize - sizeof (priv_set_t) ||
 920             prp->pfr_loff > da.rsize - sizeof (priv_set_t) ||
 921             (prp->pfr_loff & (sizeof (priv_chunk_t) - 1)) != 0 ||
 922             (prp->pfr_ioff & (sizeof (priv_chunk_t) - 1)) != 0)
 923                 goto out;
 924 
 925         /*
 926          * Get results:
 927          *      allow/allow with additional credentials/disallow[*]
 928          *