Print this page
2917 DTrace in a zone should have limited provider access


1283  * Determine if the dte_cond of the specified ECB allows for processing of
1284  * the current probe to continue.  Note that this routine may allow continued
1285  * processing, but with access(es) stripped from the mstate's dtms_access
1286  * field.
1287  */
1288 static int
1289 dtrace_priv_probe(dtrace_state_t *state, dtrace_mstate_t *mstate,
1290     dtrace_ecb_t *ecb)
1291 {
1292         dtrace_probe_t *probe = ecb->dte_probe;
1293         dtrace_provider_t *prov = probe->dtpr_provider;
1294         dtrace_pops_t *pops = &prov->dtpv_pops;
1295         int mode = DTRACE_MODE_NOPRIV_DROP;
1296 
1297         ASSERT(ecb->dte_cond);
1298 
1299         if (pops->dtps_mode != NULL) {
1300                 mode = pops->dtps_mode(prov->dtpv_arg,
1301                     probe->dtpr_id, probe->dtpr_arg);
1302 
1303                 ASSERT((mode & DTRACE_MODE_USER) ||
1304                     (mode & DTRACE_MODE_KERNEL));
1305                 ASSERT((mode & DTRACE_MODE_NOPRIV_RESTRICT) ||
1306                     (mode & DTRACE_MODE_NOPRIV_DROP));
1307         }
1308 
1309         /*
1310          * If the dte_cond bits indicate that this consumer is only allowed to
1311          * see user-mode firings of this probe, call the provider's dtps_mode()
1312          * entry point to check that the probe was fired while in a user
1313          * context.  If that's not the case, use the policy specified by the
1314          * provider to determine if we drop the probe or merely restrict
1315          * operation.
1316          */
1317         if (ecb->dte_cond & DTRACE_COND_USERMODE) {
1318                 ASSERT(mode != DTRACE_MODE_NOPRIV_DROP);
1319 
1320                 if (!(mode & DTRACE_MODE_USER)) {
1321                         if (mode & DTRACE_MODE_NOPRIV_DROP)
1322                                 return (0);
1323 
1324                         mstate->dtms_access &= ~DTRACE_ACCESS_ARGS;
1325                 }
1326         }
1327 
1328         /*
1329          * This is more subtle than it looks. We have to be absolutely certain
1330          * that CRED() isn't going to change out from under us so it's only
1331          * legit to examine that structure if we're in constrained situations.
1332          * Currently, the only times we'll this check is if a non-super-user
1333          * has enabled the profile or syscall providers -- providers that
1334          * allow visibility of all processes. For the profile case, the check
1335          * above will ensure that we're examining a user context.


1362          * in our zone, check to see if our mode policy is to restrict rather
1363          * than to drop; if to restrict, strip away both DTRACE_ACCESS_PROC
1364          * and DTRACE_ACCESS_ARGS
1365          */
1366         if (ecb->dte_cond & DTRACE_COND_ZONEOWNER) {
1367                 cred_t *cr;
1368                 cred_t *s_cr = state->dts_cred.dcr_cred;
1369 
1370                 ASSERT(s_cr != NULL);
1371 
1372                 if ((cr = CRED()) == NULL ||
1373                     s_cr->cr_zone->zone_id != cr->cr_zone->zone_id) {
1374                         if (mode & DTRACE_MODE_NOPRIV_DROP)
1375                                 return (0);
1376 
1377                         mstate->dtms_access &=
1378                             ~(DTRACE_ACCESS_PROC | DTRACE_ACCESS_ARGS);
1379                 }
1380         }
1381 









1382         return (1);
1383 }
1384 
1385 /*
1386  * Note:  not called from probe context.  This function is called
1387  * asynchronously (and at a regular interval) from outside of probe context to
1388  * clean the dirty dynamic variable lists on all CPUs.  Dynamic variable
1389  * cleaning is explained in detail in <sys/dtrace_impl.h>.
1390  */
1391 void
1392 dtrace_dynvar_clean(dtrace_dstate_t *dstate)
1393 {
1394         dtrace_dynvar_t *dirty;
1395         dtrace_dstate_percpu_t *dcpu;
1396         dtrace_dynvar_t **rinsep;
1397         int i, j, work = 0;
1398 
1399         for (i = 0; i < NCPU; i++) {
1400                 dcpu = &dstate->dtds_percpu[i];
1401                 rinsep = &dcpu->dtdsc_rinsing;




1283  * Determine if the dte_cond of the specified ECB allows for processing of
1284  * the current probe to continue.  Note that this routine may allow continued
1285  * processing, but with access(es) stripped from the mstate's dtms_access
1286  * field.
1287  */
1288 static int
1289 dtrace_priv_probe(dtrace_state_t *state, dtrace_mstate_t *mstate,
1290     dtrace_ecb_t *ecb)
1291 {
1292         dtrace_probe_t *probe = ecb->dte_probe;
1293         dtrace_provider_t *prov = probe->dtpr_provider;
1294         dtrace_pops_t *pops = &prov->dtpv_pops;
1295         int mode = DTRACE_MODE_NOPRIV_DROP;
1296 
1297         ASSERT(ecb->dte_cond);
1298 
1299         if (pops->dtps_mode != NULL) {
1300                 mode = pops->dtps_mode(prov->dtpv_arg,
1301                     probe->dtpr_id, probe->dtpr_arg);
1302 
1303                 ASSERT(mode & (DTRACE_MODE_USER | DTRACE_MODE_KERNEL));
1304                 ASSERT(mode & (DTRACE_MODE_NOPRIV_RESTRICT |
1305                     DTRACE_MODE_NOPRIV_DROP));

1306         }
1307 
1308         /*
1309          * If the dte_cond bits indicate that this consumer is only allowed to
1310          * see user-mode firings of this probe, check that the probe was fired
1311          * while in a user context.  If that's not the case, use the policy
1312          * specified by the provider to determine if we drop the probe or
1313          * merely restrict operation.

1314          */
1315         if (ecb->dte_cond & DTRACE_COND_USERMODE) {
1316                 ASSERT(mode != DTRACE_MODE_NOPRIV_DROP);
1317 
1318                 if (!(mode & DTRACE_MODE_USER)) {
1319                         if (mode & DTRACE_MODE_NOPRIV_DROP)
1320                                 return (0);
1321 
1322                         mstate->dtms_access &= ~DTRACE_ACCESS_ARGS;
1323                 }
1324         }
1325 
1326         /*
1327          * This is more subtle than it looks. We have to be absolutely certain
1328          * that CRED() isn't going to change out from under us so it's only
1329          * legit to examine that structure if we're in constrained situations.
1330          * Currently, the only times we'll this check is if a non-super-user
1331          * has enabled the profile or syscall providers -- providers that
1332          * allow visibility of all processes. For the profile case, the check
1333          * above will ensure that we're examining a user context.


1360          * in our zone, check to see if our mode policy is to restrict rather
1361          * than to drop; if to restrict, strip away both DTRACE_ACCESS_PROC
1362          * and DTRACE_ACCESS_ARGS
1363          */
1364         if (ecb->dte_cond & DTRACE_COND_ZONEOWNER) {
1365                 cred_t *cr;
1366                 cred_t *s_cr = state->dts_cred.dcr_cred;
1367 
1368                 ASSERT(s_cr != NULL);
1369 
1370                 if ((cr = CRED()) == NULL ||
1371                     s_cr->cr_zone->zone_id != cr->cr_zone->zone_id) {
1372                         if (mode & DTRACE_MODE_NOPRIV_DROP)
1373                                 return (0);
1374 
1375                         mstate->dtms_access &=
1376                             ~(DTRACE_ACCESS_PROC | DTRACE_ACCESS_ARGS);
1377                 }
1378         }
1379 
1380         /*
1381          * By merits of being in this code path at all, we have limited
1382          * privileges.  If the provider has indicated that limited privileges
1383          * are to denote restricted operation, strip off the ability to access
1384          * arguments.
1385          */
1386         if (mode & DTRACE_MODE_LIMITEDPRIV_RESTRICT)
1387                 mstate->dtms_access &= ~DTRACE_ACCESS_ARGS;
1388 
1389         return (1);
1390 }
1391 
1392 /*
1393  * Note:  not called from probe context.  This function is called
1394  * asynchronously (and at a regular interval) from outside of probe context to
1395  * clean the dirty dynamic variable lists on all CPUs.  Dynamic variable
1396  * cleaning is explained in detail in <sys/dtrace_impl.h>.
1397  */
1398 void
1399 dtrace_dynvar_clean(dtrace_dstate_t *dstate)
1400 {
1401         dtrace_dynvar_t *dirty;
1402         dtrace_dstate_percpu_t *dcpu;
1403         dtrace_dynvar_t **rinsep;
1404         int i, j, work = 0;
1405 
1406         for (i = 0; i < NCPU; i++) {
1407                 dcpu = &dstate->dtds_percpu[i];
1408                 rinsep = &dcpu->dtdsc_rinsing;