diff options
author | dp <none@none> | 2006-03-24 18:42:51 -0800 |
---|---|---|
committer | dp <none@none> | 2006-03-24 18:42:51 -0800 |
commit | ad4023c40b055806dce2bde9ee9e87e5016b5135 (patch) | |
tree | 896ea7c87446dd355a7bbb90691519097b6bde74 /usr/src | |
parent | 45916cd2fec6e79bca5dee0421bd39e3c2910d1e (diff) | |
download | illumos-joyent-ad4023c40b055806dce2bde9ee9e87e5016b5135.tar.gz |
4970596 RFE: should be able to run some DTrace programs in a zone
6231905 PRIV_DTRACE_PROC and PRIV_DTRACE_USER don't respect PRIV_PROC_ZONE
6388070 non-root non-global zone users can't get dtrace provider modules to load
6393431 dtrace_proc + proc_owner doesn't sufficiently enable destructive actions
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_error.c | 10 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_impl.h | 10 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_open.c | 6 | ||||
-rw-r--r-- | usr/src/lib/libzonecfg/common/libzonecfg.c | 3 | ||||
-rw-r--r-- | usr/src/pkgdefs/common_files/i.minorperm_i386 | 14 | ||||
-rw-r--r-- | usr/src/pkgdefs/common_files/i.minorperm_sparc | 9 | ||||
-rw-r--r-- | usr/src/uts/common/dtrace/dtrace.c | 333 | ||||
-rw-r--r-- | usr/src/uts/common/dtrace/fasttrap.c | 26 | ||||
-rw-r--r-- | usr/src/uts/common/dtrace/lockstat.c | 11 | ||||
-rw-r--r-- | usr/src/uts/common/dtrace/profile.c | 9 | ||||
-rw-r--r-- | usr/src/uts/common/dtrace/systrace.c | 9 | ||||
-rw-r--r-- | usr/src/uts/common/sys/dtrace.h | 36 | ||||
-rw-r--r-- | usr/src/uts/common/sys/dtrace_impl.h | 47 | ||||
-rw-r--r-- | usr/src/uts/intel/dtrace/fbt.c | 9 | ||||
-rw-r--r-- | usr/src/uts/intel/dtrace/sdt.c | 9 | ||||
-rw-r--r-- | usr/src/uts/intel/os/minor_perm | 6 | ||||
-rw-r--r-- | usr/src/uts/sparc/dtrace/fbt.c | 9 | ||||
-rw-r--r-- | usr/src/uts/sparc/dtrace/sdt.c | 9 | ||||
-rw-r--r-- | usr/src/uts/sparc/os/minor_perm | 6 |
19 files changed, 407 insertions, 164 deletions
diff --git a/usr/src/lib/libdtrace/common/dt_error.c b/usr/src/lib/libdtrace/common/dt_error.c index 18ebd4887a..e8874c853f 100644 --- a/usr/src/lib/libdtrace/common/dt_error.c +++ b/usr/src/lib/libdtrace/common/dt_error.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -97,8 +96,7 @@ static const struct { { EDT_BADTRUNC, "Invalid truncation" }, { EDT_BUSY, "DTrace cannot be used when kernel debugger is active" }, { EDT_ACCESS, "DTrace requires additional privileges" }, - { EDT_GNOENT, "DTrace device not available on system" }, - { EDT_ZNOENT, "DTrace device not available in local zone" }, + { EDT_NOENT, "DTrace device not available on system" }, { EDT_BRICKED, "Abort due to systemic unresponsiveness" }, { EDT_HARDWIRE, "Failed to load language definitions" }, { EDT_ELFVERSION, "libelf is out-of-date with respect to libdtrace" }, diff --git a/usr/src/lib/libdtrace/common/dt_impl.h b/usr/src/lib/libdtrace/common/dt_impl.h index 9771276dde..acf30cd911 100644 --- a/usr/src/lib/libdtrace/common/dt_impl.h +++ b/usr/src/lib/libdtrace/common/dt_impl.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -476,8 +475,7 @@ enum { EDT_BADTRUNC, /* invalid truncation */ EDT_BUSY, /* device busy (active kernel debugger) */ EDT_ACCESS, /* insufficient privileges to use DTrace */ - EDT_GNOENT, /* dtrace device not available in global zone */ - EDT_ZNOENT, /* dtrace device not available in local zone */ + EDT_NOENT, /* dtrace device not available */ EDT_BRICKED, /* abort due to systemic unresponsiveness */ EDT_HARDWIRE, /* failed to load hard-wired definitions */ EDT_ELFVERSION, /* libelf is out-of-date w.r.t libdtrace */ diff --git a/usr/src/lib/libdtrace/common/dt_open.c b/usr/src/lib/libdtrace/common/dt_open.c index 0579ca160d..b857661728 100644 --- a/usr/src/lib/libdtrace/common/dt_open.c +++ b/usr/src/lib/libdtrace/common/dt_open.c @@ -39,7 +39,6 @@ #include <stdio.h> #include <fcntl.h> #include <errno.h> -#include <zone.h> #include <assert.h> #define _POSIX_PTHREAD_SEMANTICS @@ -820,10 +819,7 @@ dt_vopen(int version, int flags, int *errp, dt_provmod_destroy(&provmod); switch (err) { case ENOENT: - if (getzoneid() != GLOBAL_ZONEID) - err = EDT_ZNOENT; - else - err = EDT_GNOENT; + err = EDT_NOENT; break; case EBUSY: err = EDT_BUSY; diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c index cede45643a..db3512727c 100644 --- a/usr/src/lib/libzonecfg/common/libzonecfg.c +++ b/usr/src/lib/libzonecfg/common/libzonecfg.c @@ -2283,7 +2283,8 @@ static const char *standard_devs[] = { "openprom", #endif "cpu/self/cpuid", - "dtrace/helper", + "dtrace/*", + "dtrace/provider/*", "zfs", NULL }; diff --git a/usr/src/pkgdefs/common_files/i.minorperm_i386 b/usr/src/pkgdefs/common_files/i.minorperm_i386 index 322e388ab6..71d802e5ff 100644 --- a/usr/src/pkgdefs/common_files/i.minorperm_i386 +++ b/usr/src/pkgdefs/common_files/i.minorperm_i386 @@ -3,9 +3,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -100,6 +99,11 @@ cpc:* 0600 root sys 0666 root sys /devices/pseudo/cpc* ipf:* 0600 root sys 0666 root sys /dev/ipf pfil:* 0600 root sys 0666 root sys /dev/pfil scsi_vhci:devctl 0600 root sys 0666 root sys /devices/scsi_vhci:devctl +fbt:fbt 0600 root sys 0644 root sys /dev/dtrace/provider/fbt +lockstat:* 0600 root sys 0644 root sys /dev/dtrace/provider/lockstat +profile:profile 0600 root sys 0644 root sys /dev/dtrace/provider/profile +sdt:sdt 0600 root sys 0644 root sys /dev/dtrace/provider/sdt +systrace:systrace 0600 root sys 0644 root sys /dev/dtrace/provider/systrace EOF } @@ -225,6 +229,10 @@ zfs:* zfs:zfs scsi_vhci:* kssl:* +fbt:fbt +profile:profile +sdt:sdt +systrace:systrace EOF } diff --git a/usr/src/pkgdefs/common_files/i.minorperm_sparc b/usr/src/pkgdefs/common_files/i.minorperm_sparc index 5b4454301f..345689d556 100644 --- a/usr/src/pkgdefs/common_files/i.minorperm_sparc +++ b/usr/src/pkgdefs/common_files/i.minorperm_sparc @@ -104,6 +104,11 @@ pcelx:* 0600 root sys 0666 root sys /dev/pcelx* ipf:* 0600 root sys 0666 root sys /dev/ipf pfil:* 0600 root sys 0666 root sys /dev/pfil scsi_vhci:devctl 0600 root sys 0666 root sys /devices/scsi_vhci:devctl +fbt:fbt 0600 root sys 0644 root sys /dev/dtrace/provider/fbt +lockstat:* 0600 root sys 0644 root sys /dev/dtrace/provider/lockstat +profile:profile 0600 root sys 0644 root sys /dev/dtrace/provider/profile +sdt:sdt 0600 root sys 0644 root sys /dev/dtrace/provider/sdt +systrace:systrace 0600 root sys 0644 root sys /dev/dtrace/provider/systrace EOF } @@ -275,6 +280,10 @@ zfs:* zfs:zfs scsi_vhci:* kssl:* +fbt:fbt +profile:profile +sdt:sdt +systrace:systrace EOF } diff --git a/usr/src/uts/common/dtrace/dtrace.c b/usr/src/uts/common/dtrace/dtrace.c index ebc91a7319..3ee6670006 100644 --- a/usr/src/uts/common/dtrace/dtrace.c +++ b/usr/src/uts/common/dtrace/dtrace.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -785,40 +784,95 @@ dtrace_bzero(void *dst, size_t len) } /* - * This privilege checks should be used by actions and subroutines to - * verify the credentials of the process that enabled the invoking ECB. + * This privilege check should be used by actions and subroutines to + * verify that the user credentials of the process that enabled the + * invoking ECB match the target credentials */ static int -dtrace_priv_proc_common(dtrace_state_t *state) +dtrace_priv_proc_common_user(dtrace_state_t *state) { - uid_t uid = state->dts_cred.dcr_uid; - gid_t gid = state->dts_cred.dcr_gid; - cred_t *cr; - proc_t *proc; + cred_t *cr, *s_cr = state->dts_cred.dcr_cred; + + /* + * We should always have a non-NULL state cred here, since if cred + * is null (anonymous tracing), we fast-path bypass this routine. + */ + ASSERT(s_cr != NULL); if ((cr = CRED()) != NULL && - uid == cr->cr_uid && - uid == cr->cr_ruid && - uid == cr->cr_suid && - gid == cr->cr_gid && - gid == cr->cr_rgid && - gid == cr->cr_sgid && - (proc = ttoproc(curthread)) != NULL && - !(proc->p_flag & SNOCD)) + s_cr->cr_uid == cr->cr_uid && + s_cr->cr_uid == cr->cr_ruid && + s_cr->cr_uid == cr->cr_suid && + s_cr->cr_gid == cr->cr_gid && + s_cr->cr_gid == cr->cr_rgid && + s_cr->cr_gid == cr->cr_sgid) return (1); - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; + return (0); +} + +/* + * This privilege check should be used by actions and subroutines to + * verify that the zone of the process that enabled the invoking ECB + * matches the target credentials + */ +static int +dtrace_priv_proc_common_zone(dtrace_state_t *state) +{ + cred_t *cr, *s_cr = state->dts_cred.dcr_cred; + + /* + * We should always have a non-NULL state cred here, since if cred + * is null (anonymous tracing), we fast-path bypass this routine. + */ + ASSERT(s_cr != NULL); + + if ((cr = CRED()) != NULL && + s_cr->cr_zone == cr->cr_zone) + return (1); return (0); } +/* + * This privilege check should be used by actions and subroutines to + * verify that the process has not setuid or changed credentials. + */ static int -dtrace_priv_proc_destructive(dtrace_state_t *state) +dtrace_priv_proc_common_nocd() { - if (state->dts_cred.dcr_action & DTRACE_CRA_PROC_DESTRUCTIVE) + proc_t *proc; + + if ((proc = ttoproc(curthread)) != NULL && + !(proc->p_flag & SNOCD)) return (1); - return (dtrace_priv_proc_common(state)); + return (0); +} + +static int +dtrace_priv_proc_destructive(dtrace_state_t *state) +{ + int action = state->dts_cred.dcr_action; + + if (((action & DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE) == 0) && + dtrace_priv_proc_common_zone(state) == 0) + goto bad; + + if (((action & DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER) == 0) && + dtrace_priv_proc_common_user(state) == 0) + goto bad; + + if (((action & DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG) == 0) && + dtrace_priv_proc_common_nocd() == 0) + goto bad; + + return (1); + +bad: + cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; + + return (0); } static int @@ -827,7 +881,14 @@ dtrace_priv_proc_control(dtrace_state_t *state) if (state->dts_cred.dcr_action & DTRACE_CRA_PROC_CONTROL) return (1); - return (dtrace_priv_proc_common(state)); + if (dtrace_priv_proc_common_zone(state) && + dtrace_priv_proc_common_user(state) && + dtrace_priv_proc_common_nocd()) + return (1); + + cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; + + return (0); } static int @@ -4719,22 +4780,36 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, * we're examining a user context. */ if (ecb->dte_cond & DTRACE_COND_OWNER) { - uid_t uid = ecb->dte_state->dts_cred.dcr_uid; - gid_t gid = ecb->dte_state->dts_cred.dcr_gid; cred_t *cr; + cred_t *s_cr = + ecb->dte_state->dts_cred.dcr_cred; proc_t *proc; + ASSERT(s_cr != NULL); + if ((cr = CRED()) == NULL || - uid != cr->cr_uid || - uid != cr->cr_ruid || - uid != cr->cr_suid || - gid != cr->cr_gid || - gid != cr->cr_rgid || - gid != cr->cr_sgid || + s_cr->cr_uid != cr->cr_uid || + s_cr->cr_uid != cr->cr_ruid || + s_cr->cr_uid != cr->cr_suid || + s_cr->cr_gid != cr->cr_gid || + s_cr->cr_gid != cr->cr_rgid || + s_cr->cr_gid != cr->cr_sgid || (proc = ttoproc(curthread)) == NULL || (proc->p_flag & SNOCD)) continue; + } + if (ecb->dte_cond & DTRACE_COND_ZONEOWNER) { + cred_t *cr; + cred_t *s_cr = + ecb->dte_state->dts_cred.dcr_cred; + + ASSERT(s_cr != NULL); + + if ((cr = CRED()) == NULL || + s_cr->cr_zone->zone_id != + cr->cr_zone->zone_id) + continue; } } @@ -5421,11 +5496,12 @@ dtrace_badname(const char *s) } static void -dtrace_cred2priv(cred_t *cr, uint32_t *privp, uid_t *uidp) +dtrace_cred2priv(cred_t *cr, uint32_t *privp, uid_t *uidp, zoneid_t *zoneidp) { uint32_t priv; *uidp = crgetuid(cr); + *zoneidp = crgetzoneid(cr); if (PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) { priv = DTRACE_PRIV_ALL; } else { @@ -5438,6 +5514,8 @@ dtrace_cred2priv(cred_t *cr, uint32_t *privp, uid_t *uidp) priv |= DTRACE_PRIV_PROC; if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE)) priv |= DTRACE_PRIV_OWNER; + if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE)) + priv |= DTRACE_PRIV_ZONEOWNER; } *privp = priv; @@ -5483,7 +5561,8 @@ out: * a probe tuple, or some globbed expressions for elements of a probe tuple. */ static int -dtrace_match_priv(const dtrace_probe_t *prp, uint32_t priv, uid_t uid) +dtrace_match_priv(const dtrace_probe_t *prp, uint32_t priv, uid_t uid, + zoneid_t zoneid) { if (priv != DTRACE_PRIV_ALL) { uint32_t ppriv = prp->dtpr_provider->dtpv_priv.dtpp_flags; @@ -5506,8 +5585,18 @@ dtrace_match_priv(const dtrace_probe_t *prp, uint32_t priv, uid_t uid) * Need to have permissions to the process, but don't... */ if (((ppriv & ~match) & DTRACE_PRIV_OWNER) != 0 && - uid != prp->dtpr_provider->dtpv_priv.dtpp_uid) + uid != prp->dtpr_provider->dtpv_priv.dtpp_uid) { return (0); + } + + /* + * Need to be in the same zone unless we possess the + * privilege to examine all zones. + */ + if (((ppriv & ~match) & DTRACE_PRIV_ZONEOWNER) != 0 && + zoneid != prp->dtpr_provider->dtpv_priv.dtpp_zoneid) { + return (0); + } } return (1); @@ -5520,7 +5609,7 @@ dtrace_match_priv(const dtrace_probe_t *prp, uint32_t priv, uid_t uid) */ static int dtrace_match_probe(const dtrace_probe_t *prp, const dtrace_probekey_t *pkp, - uint32_t priv, uid_t uid) + uint32_t priv, uid_t uid, zoneid_t zoneid) { dtrace_provider_t *pvp = prp->dtpr_provider; int rv; @@ -5540,7 +5629,7 @@ dtrace_match_probe(const dtrace_probe_t *prp, const dtrace_probekey_t *pkp, if ((rv = pkp->dtpk_nmatch(prp->dtpr_name, pkp->dtpk_name, 0)) <= 0) return (rv); - if (dtrace_match_priv(prp, priv, uid) == 0) + if (dtrace_match_priv(prp, priv, uid, zoneid) == 0) return (0); return (rv); @@ -5687,7 +5776,7 @@ dtrace_match_nonzero(const char *s, const char *p, int depth) static int dtrace_match(const dtrace_probekey_t *pkp, uint32_t priv, uid_t uid, - int (*matched)(dtrace_probe_t *, void *), void *arg) + zoneid_t zoneid, int (*matched)(dtrace_probe_t *, void *), void *arg) { dtrace_probe_t template, *probe; dtrace_hash_t *hash = NULL; @@ -5702,7 +5791,7 @@ dtrace_match(const dtrace_probekey_t *pkp, uint32_t priv, uid_t uid, */ if (pkp->dtpk_id != DTRACE_IDNONE) { if ((probe = dtrace_probe_lookup_id(pkp->dtpk_id)) != NULL && - dtrace_match_probe(probe, pkp, priv, uid) > 0) { + dtrace_match_probe(probe, pkp, priv, uid, zoneid) > 0) { (void) (*matched)(probe, arg); nmatched++; } @@ -5744,7 +5833,8 @@ dtrace_match(const dtrace_probekey_t *pkp, uint32_t priv, uid_t uid, if (hash == NULL) { for (i = 0; i < dtrace_nprobes; i++) { if ((probe = dtrace_probes[i]) == NULL || - dtrace_match_probe(probe, pkp, priv, uid) <= 0) + dtrace_match_probe(probe, pkp, priv, uid, + zoneid) <= 0) continue; nmatched++; @@ -5764,7 +5854,7 @@ dtrace_match(const dtrace_probekey_t *pkp, uint32_t priv, uid_t uid, for (probe = dtrace_hash_lookup(hash, &template); probe != NULL; probe = *(DTRACE_HASHNEXT(hash, probe))) { - if (dtrace_match_probe(probe, pkp, priv, uid) <= 0) + if (dtrace_match_probe(probe, pkp, priv, uid, zoneid) <= 0) continue; nmatched++; @@ -5844,7 +5934,7 @@ dtrace_probekey(const dtrace_probedesc_t *pdp, dtrace_probekey_t *pkp) */ int dtrace_register(const char *name, const dtrace_pattr_t *pap, uint32_t priv, - uid_t uid, const dtrace_pops_t *pops, void *arg, dtrace_provider_id_t *idp) + cred_t *cr, const dtrace_pops_t *pops, void *arg, dtrace_provider_id_t *idp) { dtrace_provider_t *provider; @@ -5899,7 +5989,10 @@ dtrace_register(const char *name, const dtrace_pattr_t *pap, uint32_t priv, provider->dtpv_attr = *pap; provider->dtpv_priv.dtpp_flags = priv; - provider->dtpv_priv.dtpp_uid = uid; + if (cr != NULL) { + provider->dtpv_priv.dtpp_uid = crgetuid(cr); + provider->dtpv_priv.dtpp_zoneid = crgetzoneid(cr); + } provider->dtpv_pops = *pops; if (pops->dtps_provide == NULL) { @@ -6344,7 +6437,7 @@ dtrace_probe_lookup(dtrace_provider_id_t prid, const char *mod, pkey.dtpk_id = DTRACE_IDNONE; mutex_enter(&dtrace_lock); - match = dtrace_match(&pkey, DTRACE_PRIV_ALL, 0, + match = dtrace_match(&pkey, DTRACE_PRIV_ALL, 0, 0, dtrace_probe_lookup_match, &id); mutex_exit(&dtrace_lock); @@ -6491,6 +6584,7 @@ dtrace_probe_enable(const dtrace_probedesc_t *desc, dtrace_enabling_t *enab) dtrace_probekey_t pkey; uint32_t priv; uid_t uid; + zoneid_t zoneid; ASSERT(MUTEX_HELD(&dtrace_lock)); dtrace_ecb_create_cache = NULL; @@ -6505,9 +6599,10 @@ dtrace_probe_enable(const dtrace_probedesc_t *desc, dtrace_enabling_t *enab) } dtrace_probekey(desc, &pkey); - dtrace_cred2priv(CRED(), &priv, &uid); + dtrace_cred2priv(CRED(), &priv, &uid, &zoneid); - return (dtrace_match(&pkey, priv, uid, dtrace_ecb_create_enable, enab)); + return (dtrace_match(&pkey, priv, uid, zoneid, dtrace_ecb_create_enable, + enab)); } /* @@ -8836,12 +8931,26 @@ dtrace_ecb_create(dtrace_state_t *state, dtrace_probe_t *probe, * enough to see, we need to enable the appropriate implicit * predicate bits to prevent the ecb from activating at * revealing times. + * + * Providers specifying DTRACE_PRIV_USER at register time + * are stating that they need the /proc-style privilege + * model to be enforced, and this is what DTRACE_COND_OWNER + * and DTRACE_COND_ZONEOWNER will then do at probe time. */ prov = probe->dtpr_provider; if (!(state->dts_cred.dcr_visible & DTRACE_CRV_ALLPROC) && (prov->dtpv_priv.dtpp_flags & DTRACE_PRIV_USER)) ecb->dte_cond |= DTRACE_COND_OWNER; + if (!(state->dts_cred.dcr_visible & DTRACE_CRV_ALLZONE) && + (prov->dtpv_priv.dtpp_flags & DTRACE_PRIV_USER)) + ecb->dte_cond |= DTRACE_COND_ZONEOWNER; + + /* + * If the provider shows us kernel innards and the user + * is lacking sufficient privilege, enable the + * DTRACE_COND_USERMODE implicit predicate. + */ if (!(state->dts_cred.dcr_visible & DTRACE_CRV_KERNEL) && (prov->dtpv_priv.dtpp_flags & DTRACE_PRIV_KERNEL)) ecb->dte_cond |= DTRACE_COND_USERMODE; @@ -9014,7 +9123,8 @@ dtrace_buffer_alloc(dtrace_buffer_t *bufs, size_t size, int flags, ASSERT(MUTEX_HELD(&cpu_lock)); ASSERT(MUTEX_HELD(&dtrace_lock)); - if (crgetuid(CRED()) != 0 && size > dtrace_nonroot_maxsize) + if (size > dtrace_nonroot_maxsize && + !PRIV_POLICY_CHOICE(CRED(), PRIV_ALL, B_FALSE)) return (EFBIG); cp = cpu_list; @@ -11071,36 +11181,128 @@ dtrace_state_create(dev_t *devp, cred_t *cr) state->dts_activity = DTRACE_ACTIVITY_INACTIVE; /* - * Set up the credentials for this instantiation. + * Depending on the user credentials, we set flag bits which alter probe + * visibility or the amount of destructiveness allowed. In the case of + * actual anonymous tracing, or the possession of all privileges, all of + * the normal checks are bypassed. */ if (cr == NULL || PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) { state->dts_cred.dcr_visible = DTRACE_CRV_ALL; state->dts_cred.dcr_action = DTRACE_CRA_ALL; } else { - state->dts_cred.dcr_uid = crgetuid(cr); - state->dts_cred.dcr_gid = crgetgid(cr); + /* + * Set up the credentials for this instantiation. We take a + * hold on the credential to prevent it from disappearing on + * us; this in turn prevents the zone_t referenced by this + * credential from disappearing. This means that we can + * examine the credential and the zone from probe context. + */ + crhold(cr); + state->dts_cred.dcr_cred = cr; + /* + * CRA_PROC means "we have *some* privilege for dtrace" and + * unlocks the use of variables like pid, zonename, etc. + */ if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE) || PRIV_POLICY_ONLY(cr, PRIV_DTRACE_PROC, B_FALSE)) { state->dts_cred.dcr_action |= DTRACE_CRA_PROC; } - if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE) && - PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE)) { - state->dts_cred.dcr_visible |= DTRACE_CRV_ALLPROC; - state->dts_cred.dcr_action |= - DTRACE_CRA_PROC_DESTRUCTIVE; + /* + * dtrace_user allows use of syscall and profile providers. + * If the user also has proc_owner and/or proc_zone, we + * extend the scope to include additional visibility and + * destructive power. + */ + if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE)) { + if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE)) { + state->dts_cred.dcr_visible |= + DTRACE_CRV_ALLPROC; + + state->dts_cred.dcr_action |= + DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER; + } + + if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE)) { + state->dts_cred.dcr_visible |= + DTRACE_CRV_ALLZONE; + + state->dts_cred.dcr_action |= + DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE; + } + + /* + * If we have all privs in whatever zone this is, + * we can do destructive things to processes which + * have altered credentials. + */ + if (priv_isequalset(priv_getset(cr, PRIV_EFFECTIVE), + cr->cr_zone->zone_privset)) { + state->dts_cred.dcr_action |= + DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG; + } } + /* + * Holding the dtrace_kernel privilege also implies that + * the user has the dtrace_user privilege from a visibility + * perspective. But without further privileges, some + * destructive actions are not available. + */ if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_KERNEL, B_FALSE)) { + /* + * Make all probes in all zones visible. However, + * this doesn't mean that all actions become available + * to all zones. + */ state->dts_cred.dcr_visible |= DTRACE_CRV_KERNEL | - DTRACE_CRV_ALLPROC; + DTRACE_CRV_ALLPROC | DTRACE_CRV_ALLZONE; + state->dts_cred.dcr_action |= DTRACE_CRA_KERNEL | DTRACE_CRA_PROC; + /* + * Holding proc_owner means that destructive actions + * for *this* zone are allowed. + */ + if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE)) + state->dts_cred.dcr_action |= + DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER; + + /* + * Holding proc_zone means that destructive actions + * for this user/group ID in all zones is allowed. + */ + if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE)) + state->dts_cred.dcr_action |= + DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE; + /* + * If we have all privs in whatever zone this is, + * we can do destructive things to processes which + * have altered credentials. + */ + if (priv_isequalset(priv_getset(cr, PRIV_EFFECTIVE), + cr->cr_zone->zone_privset)) { + state->dts_cred.dcr_action |= + DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG; + } + } + + /* + * Holding the dtrace_proc privilege gives control over fasttrap + * and pid providers. We need to grant wider destructive + * privileges in the event that the user has proc_owner and/or + * proc_zone. + */ + if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_PROC, B_FALSE)) { if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE)) state->dts_cred.dcr_action |= - DTRACE_CRA_PROC_DESTRUCTIVE; + DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER; + + if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE)) + state->dts_cred.dcr_action |= + DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE; } } @@ -11622,6 +11824,12 @@ dtrace_state_destroy(dtrace_state_t *state) ASSERT(state->dts_nretained == 0); /* + * Release the credential hold we took in dtrace_state_create(). + */ + if (state->dts_cred.dcr_cred != NULL) + crfree(state->dts_cred.dcr_cred); + + /* * Now we need to disable and destroy any enabled probes. Because any * DTRACE_PRIV_KERNEL probes may actually be slowing our progress * (especially if they're all enabled), we take two passes through @@ -13136,6 +13344,7 @@ dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) dtrace_state_t *state; uint32_t priv; uid_t uid; + zoneid_t zoneid; if (getminor(*devp) == DTRACEMNRN_HELPER) return (0); @@ -13150,7 +13359,7 @@ dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) * If no DTRACE_PRIV_* bits are set in the credential, then the * caller lacks sufficient permission to do anything with DTrace. */ - dtrace_cred2priv(cred_p, &priv, &uid); + dtrace_cred2priv(cred_p, &priv, &uid, &zoneid); if (priv == DTRACE_PRIV_NONE) return (EACCES); @@ -13606,6 +13815,7 @@ dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv) int m = 0; uint32_t priv; uid_t uid; + zoneid_t zoneid; if (copyin((void *)arg, &desc, sizeof (desc)) != 0) return (EFAULT); @@ -13631,8 +13841,7 @@ dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv) pkey.dtpk_id = DTRACE_IDNONE; } - uid = crgetuid(cr); - dtrace_cred2priv(cr, &priv, &uid); + dtrace_cred2priv(cr, &priv, &uid, &zoneid); mutex_enter(&dtrace_lock); @@ -13640,7 +13849,7 @@ dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv) for (i = desc.dtpd_id; i <= dtrace_nprobes; i++) { if ((probe = dtrace_probes[i - 1]) != NULL && (m = dtrace_match_probe(probe, &pkey, - priv, uid)) != 0) + priv, uid, zoneid)) != 0) break; } @@ -13652,7 +13861,7 @@ dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv) } else { for (i = desc.dtpd_id; i <= dtrace_nprobes; i++) { if ((probe = dtrace_probes[i - 1]) != NULL && - dtrace_match_priv(probe, priv, uid)) + dtrace_match_priv(probe, priv, uid, zoneid)) break; } } diff --git a/usr/src/uts/common/dtrace/fasttrap.c b/usr/src/uts/common/dtrace/fasttrap.c index 57fb51c44b..3829012db5 100644 --- a/usr/src/uts/common/dtrace/fasttrap.c +++ b/usr/src/uts/common/dtrace/fasttrap.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1278,7 +1277,7 @@ fasttrap_provider_lookup(pid_t pid, const char *name, fasttrap_bucket_t *bucket; char provname[DTRACE_PROVNAMELEN]; proc_t *p; - uid_t uid = (uid_t)-1; + cred_t *cred; ASSERT(strlen(name) < sizeof (fp->ftp_name)); ASSERT(pattr != NULL); @@ -1306,8 +1305,7 @@ fasttrap_provider_lookup(pid_t pid, const char *name, /* * Make sure the process exists, isn't a child created as the result - * of a vfork(2), and isn't a zombie (but may be in fork). Record the - * process's uid to pass to dtrace_register(). + * of a vfork(2), and isn't a zombie (but may be in fork). */ mutex_enter(&pidlock); if ((p = prfind(pid)) == NULL) { @@ -1328,8 +1326,13 @@ fasttrap_provider_lookup(pid_t pid, const char *name, */ p->p_dtrace_probes++; + /* + * Grab the credentials for this process so we have + * something to pass to dtrace_register(). + */ mutex_enter(&p->p_crlock); - uid = crgetruid(p->p_cred); + crhold(p->p_cred); + cred = p->p_cred; mutex_exit(&p->p_crlock); mutex_exit(&p->p_lock); @@ -1351,6 +1354,7 @@ fasttrap_provider_lookup(pid_t pid, const char *name, mutex_enter(&fp->ftp_mtx); mutex_exit(&bucket->ftb_mtx); fasttrap_provider_free(new_fp); + crfree(cred); return (fp); } } @@ -1367,11 +1371,12 @@ fasttrap_provider_lookup(pid_t pid, const char *name, if (snprintf(provname, sizeof (provname), "%s%u", name, (uint_t)pid) >= sizeof (provname) || dtrace_register(provname, pattr, - DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER, uid, + DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER | DTRACE_PRIV_ZONEOWNER, cred, pattr == &pid_attr ? &pid_pops : &usdt_pops, new_fp, &new_fp->ftp_provid) != 0) { mutex_exit(&bucket->ftb_mtx); fasttrap_provider_free(new_fp); + crfree(cred); return (NULL); } @@ -1381,6 +1386,7 @@ fasttrap_provider_lookup(pid_t pid, const char *name, mutex_enter(&new_fp->ftp_mtx); mutex_exit(&bucket->ftb_mtx); + crfree(cred); return (new_fp); } @@ -2005,7 +2011,7 @@ fasttrap_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) if (ddi_create_minor_node(devi, "fasttrap", S_IFCHR, 0, DDI_PSEUDO, NULL) == DDI_FAILURE || - dtrace_register("fasttrap", &fasttrap_attr, DTRACE_PRIV_USER, 0, + dtrace_register("fasttrap", &fasttrap_attr, DTRACE_PRIV_USER, NULL, &fasttrap_pops, NULL, &fasttrap_id) != 0) { ddi_remove_minor_node(devi, NULL); return (DDI_FAILURE); diff --git a/usr/src/uts/common/dtrace/lockstat.c b/usr/src/uts/common/dtrace/lockstat.c index 09cb37ebb3..034226ae99 100644 --- a/usr/src/uts/common/dtrace/lockstat.c +++ b/usr/src/uts/common/dtrace/lockstat.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -249,8 +248,8 @@ lockstat_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) if (ddi_create_minor_node(devi, "lockstat", S_IFCHR, 0, DDI_PSEUDO, 0) == DDI_FAILURE || - dtrace_register("lockstat", &lockstat_attr, DTRACE_PRIV_KERNEL, 0, - &lockstat_pops, NULL, &lockstat_id) != 0) { + dtrace_register("lockstat", &lockstat_attr, DTRACE_PRIV_KERNEL, + NULL, &lockstat_pops, NULL, &lockstat_id) != 0) { ddi_remove_minor_node(devi, NULL); return (DDI_FAILURE); } diff --git a/usr/src/uts/common/dtrace/profile.c b/usr/src/uts/common/dtrace/profile.c index a2b926c277..8452f03640 100644 --- a/usr/src/uts/common/dtrace/profile.c +++ b/usr/src/uts/common/dtrace/profile.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -453,7 +452,7 @@ profile_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) if (ddi_create_minor_node(devi, "profile", S_IFCHR, 0, DDI_PSEUDO, NULL) == DDI_FAILURE || dtrace_register("profile", &profile_attr, - DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER, 0, + DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER, NULL, &profile_pops, NULL, &profile_id) != 0) { ddi_remove_minor_node(devi, NULL); return (DDI_FAILURE); diff --git a/usr/src/uts/common/dtrace/systrace.c b/usr/src/uts/common/dtrace/systrace.c index 366acdbc7a..5dea20a911 100644 --- a/usr/src/uts/common/dtrace/systrace.c +++ b/usr/src/uts/common/dtrace/systrace.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -247,7 +246,7 @@ systrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) if (ddi_create_minor_node(devi, "systrace", S_IFCHR, 0, DDI_PSEUDO, NULL) == DDI_FAILURE || - dtrace_register("syscall", &systrace_attr, DTRACE_PRIV_USER, 0, + dtrace_register("syscall", &systrace_attr, DTRACE_PRIV_USER, NULL, &systrace_pops, NULL, &systrace_id) != 0) { systrace_probe = systrace_stub; ddi_remove_minor_node(devi, NULL); diff --git a/usr/src/uts/common/sys/dtrace.h b/usr/src/uts/common/sys/dtrace.h index 07b58f9411..57765c1d31 100644 --- a/usr/src/uts/common/sys/dtrace.h +++ b/usr/src/uts/common/sys/dtrace.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1112,14 +1111,16 @@ typedef uint8_t dtrace_class_t; /* architectural dependency class */ #define DTRACE_PRIV_USER 0x0002 #define DTRACE_PRIV_PROC 0x0004 #define DTRACE_PRIV_OWNER 0x0008 +#define DTRACE_PRIV_ZONEOWNER 0x0010 #define DTRACE_PRIV_ALL \ (DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER | \ - DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER) + DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER | DTRACE_PRIV_ZONEOWNER) typedef struct dtrace_ppriv { uint32_t dtpp_flags; /* privilege flags */ uid_t dtpp_uid; /* user ID */ + zoneid_t dtpp_zoneid; /* zone ID */ } dtrace_ppriv_t; typedef struct dtrace_attribute { @@ -1603,7 +1604,7 @@ typedef struct dof_helper { * dtrace_probe() <-- Fire the specified probe * * 2.2 int dtrace_register(const char *name, const dtrace_pattr_t *pap, - * uint32_t priv, uid_t uid, const dtrace_pops_t *pops, void *arg, + * uint32_t priv, cred_t *cr, const dtrace_pops_t *pops, void *arg, * dtrace_provider_id_t *idp) * * 2.2.1 Overview @@ -1632,16 +1633,25 @@ typedef struct dof_helper { * DTRACE_PRIV_OWNER <= This flag places an additional constraint on * the privilege requirements above. These probes * require either (a) a user ID matching the user - * ID passed as the fourth argument to - * dtrace_register() or (b) the PRIV_PROC_OWNER - * privilege. + * ID of the cred passed in the fourth argument + * or (b) the PRIV_PROC_OWNER privilege. + * + * DTRACE_PRIV_ZONEOWNER<= This flag places an additional constraint on + * the privilege requirements above. These probes + * require either (a) a zone ID matching the zone + * ID of the cred passed in the fourth argument + * or (b) the PRIV_PROC_ZONE privilege. * * Note that these flags designate the _visibility_ of the probes, not * the conditions under which they may or may not fire. * - * The fourth argument is a user ID that is associated with the provider. - * This argument should be 0 if the privilege flags don't include - * DTRACE_PRIV_OWNER. + * The fourth argument is the credential that is associated with the + * provider. This argument should be NULL if the privilege flags don't + * include DTRACE_PRIV_OWNER or DTRACE_PRIV_ZONEOWNER. If non-NULL, the + * framework stashes the uid and zoneid represented by this credential + * for use at probe-time, in implicit predicates. These limit visibility + * of the probes to users and/or zones which have sufficient privilege to + * access them. * * The fifth argument is a DTrace provider operations vector, which provides * the implementation for the Framework-to-Provider API. (See Section 1, @@ -1937,7 +1947,7 @@ typedef struct dtrace_pops { typedef uintptr_t dtrace_provider_id_t; extern int dtrace_register(const char *, const dtrace_pattr_t *, uint32_t, - uid_t, const dtrace_pops_t *, void *, dtrace_provider_id_t *); + cred_t *, const dtrace_pops_t *, void *, dtrace_provider_id_t *); extern int dtrace_unregister(dtrace_provider_id_t); extern int dtrace_condense(dtrace_provider_id_t); extern void dtrace_invalidate(dtrace_provider_id_t); diff --git a/usr/src/uts/common/sys/dtrace_impl.h b/usr/src/uts/common/sys/dtrace_impl.h index fdb284d192..2bb12dcbfb 100644 --- a/usr/src/uts/common/sys/dtrace_impl.h +++ b/usr/src/uts/common/sys/dtrace_impl.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -914,6 +913,7 @@ typedef struct dtrace_mstate { #define DTRACE_COND_OWNER 0x1 #define DTRACE_COND_USERMODE 0x2 +#define DTRACE_COND_ZONEOWNER 0x4 #define DTRACE_PROBEKEY_MAXDEPTH 8 /* max glob recursion depth */ @@ -1039,31 +1039,38 @@ typedef struct dtrace_helptrace { /* * DTrace Credentials * - * In probe context, we don't have the flexibility to examine the credentials - * of the DTrace consumer that created a particular enabling. Instead, we use - * the Least Privilege interfaces to cache the consumer's credentials in a - * dtrace_cred_t structure. That structure contains two important sets of - * credentials that limit the consumer's breadth of visibility and what - * actions the consumer may take. + * In probe context, we have limited flexibility to examine the credentials + * of the DTrace consumer that created a particular enabling. We use + * the Least Privilege interfaces to cache the consumer's cred pointer and + * some facts about that credential in a dtrace_cred_t structure. These + * can limit the consumer's breadth of visibility and what actions the + * consumer may take. */ #define DTRACE_CRV_ALLPROC 0x01 #define DTRACE_CRV_KERNEL 0x02 +#define DTRACE_CRV_ALLZONE 0x04 -#define DTRACE_CRV_ALL (DTRACE_CRV_ALLPROC | DTRACE_CRV_KERNEL) +#define DTRACE_CRV_ALL (DTRACE_CRV_ALLPROC | DTRACE_CRV_KERNEL | \ + DTRACE_CRV_ALLZONE) -#define DTRACE_CRA_PROC 0x0001 -#define DTRACE_CRA_PROC_DESTRUCTIVE 0x0002 -#define DTRACE_CRA_PROC_CONTROL 0x0004 -#define DTRACE_CRA_KERNEL 0x0008 -#define DTRACE_CRA_KERNEL_DESTRUCTIVE 0x0010 +#define DTRACE_CRA_PROC 0x0001 +#define DTRACE_CRA_PROC_CONTROL 0x0002 +#define DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER 0x0004 +#define DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE 0x0008 +#define DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG 0x0010 +#define DTRACE_CRA_KERNEL 0x0020 +#define DTRACE_CRA_KERNEL_DESTRUCTIVE 0x0040 #define DTRACE_CRA_ALL (DTRACE_CRA_PROC | \ - DTRACE_CRA_PROC_DESTRUCTIVE | DTRACE_CRA_PROC_CONTROL | \ - DTRACE_CRA_KERNEL | DTRACE_CRA_KERNEL_DESTRUCTIVE) + DTRACE_CRA_PROC_CONTROL | \ + DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER | \ + DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE | \ + DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG | \ + DTRACE_CRA_KERNEL | \ + DTRACE_CRA_KERNEL_DESTRUCTIVE) typedef struct dtrace_cred { - uid_t dcr_uid; - gid_t dcr_gid; + cred_t *dcr_cred; uint8_t dcr_destructive; uint8_t dcr_visible; uint16_t dcr_action; diff --git a/usr/src/uts/intel/dtrace/fbt.c b/usr/src/uts/intel/dtrace/fbt.c index 3009dc6d88..40d5dbdab6 100644 --- a/usr/src/uts/intel/dtrace/fbt.c +++ b/usr/src/uts/intel/dtrace/fbt.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -719,7 +718,7 @@ fbt_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) if (ddi_create_minor_node(devi, "fbt", S_IFCHR, 0, DDI_PSEUDO, NULL) == DDI_FAILURE || - dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_KERNEL, 0, + dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_KERNEL, NULL, &fbt_pops, NULL, &fbt_id) != 0) { fbt_cleanup(devi); return (DDI_FAILURE); diff --git a/usr/src/uts/intel/dtrace/sdt.c b/usr/src/uts/intel/dtrace/sdt.c index 68c2094cbb..aa31d84d14 100644 --- a/usr/src/uts/intel/dtrace/sdt.c +++ b/usr/src/uts/intel/dtrace/sdt.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -329,7 +328,7 @@ sdt_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) { if (dtrace_register(prov->sdtp_name, prov->sdtp_attr, - DTRACE_PRIV_KERNEL, 0, + DTRACE_PRIV_KERNEL, NULL, &sdt_pops, prov, &prov->sdtp_id) != 0) { cmn_err(CE_WARN, "failed to register sdt provider %s", prov->sdtp_name); diff --git a/usr/src/uts/intel/os/minor_perm b/usr/src/uts/intel/os/minor_perm index 6a591a9f6c..2bff059569 100644 --- a/usr/src/uts/intel/os/minor_perm +++ b/usr/src/uts/intel/os/minor_perm @@ -42,12 +42,13 @@ devinfo:devinfo,ro 0444 root sys dtrace:* 0666 root sys dump:dump 0660 root sys fasttrap:fasttrap 0666 root sys +fbt:fbt 0644 root sys fd:* 0666 root sys id:* 0640 root sys kstat:* 0666 root sys ksyms:* 0666 root sys lo:* 0666 root sys -lockstat:* 0600 root sys +lockstat:* 0644 root sys lofi:* 0600 root sys lofi:ctl 0644 root sys log:conslog 0666 root sys @@ -60,6 +61,7 @@ mm:null 0666 root sys mm:zero 0666 root sys msm:l 0666 root sys openeepr:openprom 0640 root sys +profile:profile 0644 root sys ptc:* 0666 root sys pts:* 0644 root sys pts:0 0620 root tty @@ -73,9 +75,11 @@ sgen:* 0600 root sys cmdk:* 0640 root sys st:* 0666 root sys sbpro:* 0600 root sys +sdt:sdt 0644 root sys sy:tty 0666 root tty sysmsg:msglog 0600 root sys sysmsg:sysmsg 0600 root sys +systrace:systrace 0644 root sys winlock:* 0666 root sys asy:[a-z] 0666 root sys asy:[a-z],cu 0600 uucp uucp diff --git a/usr/src/uts/sparc/dtrace/fbt.c b/usr/src/uts/sparc/dtrace/fbt.c index d01f6cfb74..91adbfe22a 100644 --- a/usr/src/uts/sparc/dtrace/fbt.c +++ b/usr/src/uts/sparc/dtrace/fbt.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1728,7 +1727,7 @@ fbt_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) if (ddi_create_minor_node(devi, "fbt", S_IFCHR, 0, DDI_PSEUDO, NULL) == DDI_FAILURE || - dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_KERNEL, 0, + dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_KERNEL, NULL, &fbt_pops, NULL, &fbt_id) != 0) { ddi_remove_minor_node(devi, NULL); return (DDI_FAILURE); diff --git a/usr/src/uts/sparc/dtrace/sdt.c b/usr/src/uts/sparc/dtrace/sdt.c index 65f833dfc9..e03eedc21d 100644 --- a/usr/src/uts/sparc/dtrace/sdt.c +++ b/usr/src/uts/sparc/dtrace/sdt.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -376,7 +375,7 @@ sdt_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) { if (dtrace_register(prov->sdtp_name, prov->sdtp_attr, - DTRACE_PRIV_KERNEL, 0, + DTRACE_PRIV_KERNEL, NULL, &sdt_pops, prov, &prov->sdtp_id) != 0) { cmn_err(CE_WARN, "failed to register sdt provider %s", prov->sdtp_name); diff --git a/usr/src/uts/sparc/os/minor_perm b/usr/src/uts/sparc/os/minor_perm index 5be676b37d..7c5c275982 100644 --- a/usr/src/uts/sparc/os/minor_perm +++ b/usr/src/uts/sparc/os/minor_perm @@ -40,6 +40,7 @@ devinfo:devinfo 0640 root sys devinfo:devinfo,ro 0444 root sys dtrace:* 0666 root sys dump:dump 0660 root sys +fbt:fbt 0644 root sys fd:* 0666 root sys fasttrap:fasttrap 0666 root sys fssnap:* 0640 root sys @@ -47,7 +48,7 @@ fssnap:ctl 0666 root sys kstat:* 0666 root sys ksyms:* 0666 root sys lo:* 0666 root sys -lockstat:* 0600 root sys +lockstat:* 0644 root sys lofi:* 0600 root sys lofi:ctl 0644 root sys log:conslog 0666 root sys @@ -60,6 +61,7 @@ mm:mem 0640 root sys mm:null 0666 root sys mm:zero 0666 root sys openeepr:openprom 0640 root sys +profile:profile 0644 root sys ptc:* 0666 root sys pts:* 0644 root sys pts:0 0620 root tty @@ -71,6 +73,7 @@ sad:admin 0666 root sys sad:user 0666 root sys sd:* 0640 root sys dad:* 0640 root sys +sdt:sdt 0644 root sys sgen:* 0600 root sys ssd:* 0640 root sys st:* 0666 root sys @@ -82,6 +85,7 @@ SUNW,fdtwo:* 0666 root sys sy:tty 0666 root tty sysmsg:msglog 0600 root sys sysmsg:sysmsg 0600 root sys +systrace:systrace 0644 root sys winlock:* 0666 root sys zs:[a-z] 0666 root sys zs:[a-z],cu 0600 uucp uucp |