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 *)≺
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 *)≺
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 *
|