diff options
Diffstat (limited to 'usr/src/uts/common/dtrace/dtrace.c')
| -rw-r--r-- | usr/src/uts/common/dtrace/dtrace.c | 50 | 
1 files changed, 39 insertions, 11 deletions
| diff --git a/usr/src/uts/common/dtrace/dtrace.c b/usr/src/uts/common/dtrace/dtrace.c index 266c55fb76..4f0f882343 100644 --- a/usr/src/uts/common/dtrace/dtrace.c +++ b/usr/src/uts/common/dtrace/dtrace.c @@ -819,8 +819,8 @@ dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,  			if (DTRACE_INRANGE(addr, sz, &vp->v_path, psz))  				return (1); -			if (vp->v_path != NULL && DTRACE_INRANGE(addr, sz, -			    vp->v_path, strlen(vp->v_path) + 1)) { +			if (DTRACE_INRANGE(addr, sz, vp->v_path, +			    strlen(vp->v_path) + 1)) {  				return (1);  			} @@ -879,7 +879,7 @@ static int  dtrace_vcanload(void *src, dtrace_diftype_t *type, dtrace_mstate_t *mstate,      dtrace_vstate_t *vstate)  { -	size_t sz; +	size_t sz, strsize;  	ASSERT(type->dtdt_flags & DIF_TF_BYREF);  	/* @@ -889,11 +889,24 @@ dtrace_vcanload(void *src, dtrace_diftype_t *type, dtrace_mstate_t *mstate,  	if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0)  		return (1); -	if (type->dtdt_kind == DIF_TYPE_STRING) -		sz = dtrace_strlen(src, -		    vstate->dtvs_state->dts_options[DTRACEOPT_STRSIZE]) + 1; -	else +	if (type->dtdt_kind == DIF_TYPE_STRING) { +		dtrace_state_t *state = vstate->dtvs_state; + +		if (state != NULL) { +			strsize = state->dts_options[DTRACEOPT_STRSIZE]; +		} else { +			/* +			 * In helper context, we have a NULL state; fall back +			 * to using the system-wide default for the string size +			 * in this case. +			 */ +			strsize = dtrace_strsize_default; +		} + +		sz = dtrace_strlen(src, strsize) + 1; +	} else {  		sz = type->dtdt_size; +	}  	return (dtrace_canload((uintptr_t)src, sz, mstate, vstate));  } @@ -7565,7 +7578,7 @@ dtrace_cred2priv(cred_t *cr, uint32_t *privp, uid_t *uidp, zoneid_t *zoneidp)  		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)) @@ -8061,7 +8074,7 @@ dtrace_register(const char *name, const dtrace_pattr_t *pap, uint32_t priv,  	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; @@ -8672,6 +8685,7 @@ dtrace_probe_enable(const dtrace_probedesc_t *desc, dtrace_enabling_t *enab)  	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; @@ -8686,8 +8700,22 @@ dtrace_probe_enable(const dtrace_probedesc_t *desc, dtrace_enabling_t *enab)  	}  	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)); | 
