Print this page
OS-208 DTrace needs to use zone_did to match zone-limited enablings
INTRO-118 enabling USDT probes in zones should be more scalable
*** 7791,7801 ****
* For DTRACE_PRIV_ALL, the uid and zoneid don't matter.
*/
priv = DTRACE_PRIV_ALL;
} else {
*uidp = crgetuid(cr);
! *zoneidp = crgetzoneid(cr);
priv = 0;
if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_KERNEL, B_FALSE))
priv |= DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER;
else if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE))
--- 7791,7801 ----
* For DTRACE_PRIV_ALL, the uid and zoneid don't matter.
*/
priv = DTRACE_PRIV_ALL;
} else {
*uidp = crgetuid(cr);
! *zoneidp = crgetzonedid(cr);
priv = 0;
if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_KERNEL, B_FALSE))
priv |= DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER;
else if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE))
*** 8287,8297 ****
provider->dtpv_attr = *pap;
provider->dtpv_priv.dtpp_flags = priv;
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) {
ASSERT(pops->dtps_provide_module != NULL);
--- 8287,8297 ----
provider->dtpv_attr = *pap;
provider->dtpv_priv.dtpp_flags = priv;
if (cr != NULL) {
provider->dtpv_priv.dtpp_uid = crgetuid(cr);
! provider->dtpv_priv.dtpp_zoneid = crgetzonedid(cr);
}
provider->dtpv_pops = *pops;
if (pops->dtps_provide == NULL) {
ASSERT(pops->dtps_provide_module != NULL);
*** 8891,8900 ****
--- 8891,8901 ----
{
dtrace_probekey_t pkey;
uint32_t priv;
uid_t uid;
zoneid_t zoneid;
+ dtrace_state_t *state = enab->dten_vstate->dtvs_state;
ASSERT(MUTEX_HELD(&dtrace_lock));
dtrace_ecb_create_cache = NULL;
if (desc == NULL) {
*** 8905,8917 ****
(void) dtrace_ecb_create_enable(NULL, enab);
return (0);
}
dtrace_probekey(desc, &pkey);
! dtrace_cred2priv(enab->dten_vstate->dtvs_state->dts_cred.dcr_cred,
! &priv, &uid, &zoneid);
return (dtrace_match(&pkey, priv, uid, zoneid, dtrace_ecb_create_enable,
enab));
}
/*
--- 8906,8932 ----
(void) dtrace_ecb_create_enable(NULL, enab);
return (0);
}
dtrace_probekey(desc, &pkey);
! dtrace_cred2priv(state->dts_cred.dcr_cred, &priv, &uid, &zoneid);
+ if ((priv & DTRACE_PRIV_ZONEOWNER) &&
+ state->dts_options[DTRACEOPT_ZONE] != DTRACEOPT_UNSET) {
+ /*
+ * If we have the privilege of instrumenting all zones but we
+ * have been told to instrument but one, we will spoof this up
+ * depriving ourselves of DTRACE_PRIV_ZONEOWNER for purposes
+ * of dtrace_match(). (Note that DTRACEOPT_ZONE is not for
+ * security but rather for performance: it allows the global
+ * zone to instrument USDT probes in a local zone without
+ * requiring all zones to be instrumented.)
+ */
+ priv &= ~DTRACE_PRIV_ZONEOWNER;
+ zoneid = state->dts_options[DTRACEOPT_ZONE];
+ }
+
return (dtrace_match(&pkey, priv, uid, zoneid, dtrace_ecb_create_enable,
enab));
}
/*
*** 12368,12381 ****
* block pending our completion.
*/
for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) {
dtrace_cred_t *dcr = &enab->dten_vstate->dtvs_state->dts_cred;
cred_t *cr = dcr->dcr_cred;
! zoneid_t zone = cr != NULL ? crgetzoneid(cr) : 0;
if ((dcr->dcr_visible & DTRACE_CRV_ALLZONE) || (cr != NULL &&
! (zone == GLOBAL_ZONEID || getzoneid() == zone)))
(void) dtrace_enabling_match(enab, NULL);
}
mutex_exit(&dtrace_lock);
mutex_exit(&cpu_lock);
--- 12383,12396 ----
* block pending our completion.
*/
for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) {
dtrace_cred_t *dcr = &enab->dten_vstate->dtvs_state->dts_cred;
cred_t *cr = dcr->dcr_cred;
! zoneid_t zone = cr != NULL ? crgetzonedid(cr) : 0;
if ((dcr->dcr_visible & DTRACE_CRV_ALLZONE) || (cr != NULL &&
! (zone == GLOBAL_ZONEID || getzonedid() == zone)))
(void) dtrace_enabling_match(enab, NULL);
}
mutex_exit(&dtrace_lock);
mutex_exit(&cpu_lock);