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);