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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/dtrace/dtrace.c
          +++ new/usr/src/uts/common/dtrace/dtrace.c
↓ open down ↓ 7785 lines elided ↑ open up ↑
7786 7786  {
7787 7787          uint32_t priv;
7788 7788  
7789 7789          if (cr == NULL || PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) {
7790 7790                  /*
7791 7791                   * For DTRACE_PRIV_ALL, the uid and zoneid don't matter.
7792 7792                   */
7793 7793                  priv = DTRACE_PRIV_ALL;
7794 7794          } else {
7795 7795                  *uidp = crgetuid(cr);
7796      -                *zoneidp = crgetzoneid(cr);
     7796 +                *zoneidp = crgetzonedid(cr);
7797 7797  
7798 7798                  priv = 0;
7799 7799                  if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_KERNEL, B_FALSE))
7800 7800                          priv |= DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER;
7801 7801                  else if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE))
7802 7802                          priv |= DTRACE_PRIV_USER;
7803 7803                  if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_PROC, B_FALSE))
7804 7804                          priv |= DTRACE_PRIV_PROC;
7805 7805                  if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE))
7806 7806                          priv |= DTRACE_PRIV_OWNER;
↓ open down ↓ 475 lines elided ↑ open up ↑
8282 8282          }
8283 8283  
8284 8284          provider = kmem_zalloc(sizeof (dtrace_provider_t), KM_SLEEP);
8285 8285          provider->dtpv_name = kmem_alloc(strlen(name) + 1, KM_SLEEP);
8286 8286          (void) strcpy(provider->dtpv_name, name);
8287 8287  
8288 8288          provider->dtpv_attr = *pap;
8289 8289          provider->dtpv_priv.dtpp_flags = priv;
8290 8290          if (cr != NULL) {
8291 8291                  provider->dtpv_priv.dtpp_uid = crgetuid(cr);
8292      -                provider->dtpv_priv.dtpp_zoneid = crgetzoneid(cr);
     8292 +                provider->dtpv_priv.dtpp_zoneid = crgetzonedid(cr);
8293 8293          }
8294 8294          provider->dtpv_pops = *pops;
8295 8295  
8296 8296          if (pops->dtps_provide == NULL) {
8297 8297                  ASSERT(pops->dtps_provide_module != NULL);
8298 8298                  provider->dtpv_pops.dtps_provide = dtrace_nullop_provide;
8299 8299          }
8300 8300  
8301 8301          if (pops->dtps_provide_module == NULL) {
8302 8302                  ASSERT(pops->dtps_provide != NULL);
↓ open down ↓ 583 lines elided ↑ open up ↑
8886 8886          dtrace_interrupt_enable(cookie);
8887 8887  }
8888 8888  
8889 8889  static int
8890 8890  dtrace_probe_enable(const dtrace_probedesc_t *desc, dtrace_enabling_t *enab)
8891 8891  {
8892 8892          dtrace_probekey_t pkey;
8893 8893          uint32_t priv;
8894 8894          uid_t uid;
8895 8895          zoneid_t zoneid;
     8896 +        dtrace_state_t *state = enab->dten_vstate->dtvs_state;
8896 8897  
8897 8898          ASSERT(MUTEX_HELD(&dtrace_lock));
8898 8899          dtrace_ecb_create_cache = NULL;
8899 8900  
8900 8901          if (desc == NULL) {
8901 8902                  /*
8902 8903                   * If we're passed a NULL description, we're being asked to
8903 8904                   * create an ECB with a NULL probe.
8904 8905                   */
8905 8906                  (void) dtrace_ecb_create_enable(NULL, enab);
8906 8907                  return (0);
8907 8908          }
8908 8909  
8909 8910          dtrace_probekey(desc, &pkey);
8910      -        dtrace_cred2priv(enab->dten_vstate->dtvs_state->dts_cred.dcr_cred,
8911      -            &priv, &uid, &zoneid);
     8911 +        dtrace_cred2priv(state->dts_cred.dcr_cred, &priv, &uid, &zoneid);
8912 8912  
     8913 +        if ((priv & DTRACE_PRIV_ZONEOWNER) &&
     8914 +            state->dts_options[DTRACEOPT_ZONE] != DTRACEOPT_UNSET) {
     8915 +                /*
     8916 +                 * If we have the privilege of instrumenting all zones but we
     8917 +                 * have been told to instrument but one, we will spoof this up
     8918 +                 * depriving ourselves of DTRACE_PRIV_ZONEOWNER for purposes
     8919 +                 * of dtrace_match().  (Note that DTRACEOPT_ZONE is not for
     8920 +                 * security but rather for performance: it allows the global
     8921 +                 * zone to instrument USDT probes in a local zone without
     8922 +                 * requiring all zones to be instrumented.)
     8923 +                 */
     8924 +                priv &= ~DTRACE_PRIV_ZONEOWNER;
     8925 +                zoneid = state->dts_options[DTRACEOPT_ZONE];
     8926 +        }
     8927 +
8913 8928          return (dtrace_match(&pkey, priv, uid, zoneid, dtrace_ecb_create_enable,
8914 8929              enab));
8915 8930  }
8916 8931  
8917 8932  /*
8918 8933   * DTrace Helper Provider Functions
8919 8934   */
8920 8935  static void
8921 8936  dtrace_dofattr2attr(dtrace_attribute_t *attr, const dof_attr_t dofattr)
8922 8937  {
↓ open down ↓ 3440 lines elided ↑ open up ↑
12363 12378           * we have sufficient permissions by virtue of being in the global zone
12364 12379           * or in the same zone as the DTrace client.  Because we can be called
12365 12380           * after dtrace_detach() has been called, we cannot assert that there
12366 12381           * are retained enablings.  We can safely load from dtrace_retained,
12367 12382           * however:  the taskq_destroy() at the end of dtrace_detach() will
12368 12383           * block pending our completion.
12369 12384           */
12370 12385          for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) {
12371 12386                  dtrace_cred_t *dcr = &enab->dten_vstate->dtvs_state->dts_cred;
12372 12387                  cred_t *cr = dcr->dcr_cred;
12373      -                zoneid_t zone = cr != NULL ? crgetzoneid(cr) : 0;
     12388 +                zoneid_t zone = cr != NULL ? crgetzonedid(cr) : 0;
12374 12389  
12375 12390                  if ((dcr->dcr_visible & DTRACE_CRV_ALLZONE) || (cr != NULL &&
12376      -                    (zone == GLOBAL_ZONEID || getzoneid() == zone)))
     12391 +                    (zone == GLOBAL_ZONEID || getzonedid() == zone)))
12377 12392                          (void) dtrace_enabling_match(enab, NULL);
12378 12393          }
12379 12394  
12380 12395          mutex_exit(&dtrace_lock);
12381 12396          mutex_exit(&cpu_lock);
12382 12397  }
12383 12398  
12384 12399  /*
12385 12400   * If an enabling is to be enabled without having matched probes (that is, if
12386 12401   * dtrace_state_go() is to be called on the underlying dtrace_state_t), the
↓ open down ↓ 4927 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX