summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authordp <none@none>2006-03-24 18:42:51 -0800
committerdp <none@none>2006-03-24 18:42:51 -0800
commitad4023c40b055806dce2bde9ee9e87e5016b5135 (patch)
tree896ea7c87446dd355a7bbb90691519097b6bde74 /usr/src
parent45916cd2fec6e79bca5dee0421bd39e3c2910d1e (diff)
downloadillumos-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.c10
-rw-r--r--usr/src/lib/libdtrace/common/dt_impl.h10
-rw-r--r--usr/src/lib/libdtrace/common/dt_open.c6
-rw-r--r--usr/src/lib/libzonecfg/common/libzonecfg.c3
-rw-r--r--usr/src/pkgdefs/common_files/i.minorperm_i38614
-rw-r--r--usr/src/pkgdefs/common_files/i.minorperm_sparc9
-rw-r--r--usr/src/uts/common/dtrace/dtrace.c333
-rw-r--r--usr/src/uts/common/dtrace/fasttrap.c26
-rw-r--r--usr/src/uts/common/dtrace/lockstat.c11
-rw-r--r--usr/src/uts/common/dtrace/profile.c9
-rw-r--r--usr/src/uts/common/dtrace/systrace.c9
-rw-r--r--usr/src/uts/common/sys/dtrace.h36
-rw-r--r--usr/src/uts/common/sys/dtrace_impl.h47
-rw-r--r--usr/src/uts/intel/dtrace/fbt.c9
-rw-r--r--usr/src/uts/intel/dtrace/sdt.c9
-rw-r--r--usr/src/uts/intel/os/minor_perm6
-rw-r--r--usr/src/uts/sparc/dtrace/fbt.c9
-rw-r--r--usr/src/uts/sparc/dtrace/sdt.c9
-rw-r--r--usr/src/uts/sparc/os/minor_perm6
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