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,11 +7791,11 @@
                  * For DTRACE_PRIV_ALL, the uid and zoneid don't matter.
                  */
                 priv = DTRACE_PRIV_ALL;
         } else {
                 *uidp = crgetuid(cr);
-                *zoneidp = crgetzoneid(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,11 +8287,11 @@
 
         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_priv.dtpp_zoneid = crgetzonedid(cr);
         }
         provider->dtpv_pops = *pops;
 
         if (pops->dtps_provide == NULL) {
                 ASSERT(pops->dtps_provide_module != NULL);

@@ -8891,10 +8891,11 @@
 {
         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,13 +8906,27 @@
                 (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);
+        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,14 +12383,14 @@
          * 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;
+                zoneid_t zone = cr != NULL ? crgetzonedid(cr) : 0;
 
                 if ((dcr->dcr_visible & DTRACE_CRV_ALLZONE) || (cr != NULL &&
-                    (zone == GLOBAL_ZONEID || getzoneid() == zone)))
+                    (zone == GLOBAL_ZONEID || getzonedid() == zone)))
                         (void) dtrace_enabling_match(enab, NULL);
         }
 
         mutex_exit(&dtrace_lock);
         mutex_exit(&cpu_lock);