Discussion:
tick probes for unprivileged users
Bryan Cantrill
2011-07-09 20:42:21 UTC
Permalink
All,

A(nother) longstanding DTrace annoyance has been that tick probes,
while enableable by users with limited privilege, will only fire if
the context matches one that the user is allowed to instrument.
Specifically: if a user uses tick probes from within a zone, they
will only fire if that zone happens to be running on the CPU on which
the tick probe fires. This breaks many scripts that (naturally) use
tick probes as a kind of local timeout mechanism. For us at Joyent,
this has become a top annoyance for our customers who themselves want
to use DTrace from within the zone, so we wanted to take a swing at
addressing this -- but we also needed to be mindful (obviously) of not
allowing privilege escalation. Complicating things, I also wanted to
do this in a way that preserves the existing behavior for the profile
probes: that they don't fire when in a context that one cannot
execute is actually the easiest way of assuring that a profile-based
enabling in the non-global zone does (roughly) what the user thinks it
does. So the model we came to is to split the behavior (slightly) of
the profile provider, and use the provider's dtps_usermode (which I
have renamed to dtps_mode) to inform as to both mode (kernel mode v.
user mode) and policy (if the user cannot execute in this context,
this firing should be dropped v. restricted). When restricted, the
user does not have either proc privileges, nor the privileges
necessary to examine arguments, and attempts to do so will induce a
UPRIV or KPRIV fault (respectively). From the (new) block comment
explaining the dtps_mode entry point, the return value from dpts_mode
is:

A bitwise OR that encapsulates both the mode (either DTRACE_MODE_KERNEL
or DTRACE_MODE_USER) and the policy when the privilege of the enabling
is insufficient for that mode (either DTRACE_MODE_NOPRIV_DROP or
DTRACE_MODE_NOPRIV_RESTRICT). If the policy is DTRACE_MODE_NOPRIV_DROP,
insufficient privilege will result in the probe firing being silently
ignored for the enabling; if the policy is DTRACE_NODE_NOPRIV_RESTRICT,
insufficient privilege will not prevent probe processing for the
enabling, but restrictions will be in place that induce a UPRIV fault
upon attempt to examine probe arguments or current process state.

Attached is a patch that implements this. I have integrated this into
our bits at Joyent (internal ticket is OS-431, "dtrace profile and
tick probes sometimes don't fire in a zone"), so -- as with our other
work -- you'll see this show up soon (next two weeks or so) at
http://github.com/joyent/illumos-joyent, but I wanted to give folks an
earlier heads-up in case we want to have further discussion here. In
particular: Adam, it would be great if you could take a look at this
at some point -- though I would obviously welcome anyone else's
feedback as well!

- Bryan
Adam Leventhal
2011-07-15 16:26:22 UTC
Permalink
Hey Bryan,

This not only adds great value, but also makes the code better. Just a
couple of nits:

dtrace_prive_probe()
I think the comment belongs before the previous if block (i.e. before
we calldtps_mode())

The ASSERT: where's logical xor when you need it?!

"Currently, the only times we'll this check .." -- missing a verb

dtrace.h
The overview for dtps_mode() could be better; how about this:
Called to determine the execute mode of the fired probe and the appropriate
policy for an unprivileged firing.
Writing that, I realized that the mode is dynamic while the policy of what to
do in an unprivileged case is static and could be part of provider
registration -- but whatever.

Adam
Post by Bryan Cantrill
All,
A(nother) longstanding DTrace annoyance has been that tick probes,
while enableable by users with limited privilege, will only fire if
the context matches one that the user is allowed to instrument.
Specifically:  if a user uses tick probes from within a zone, they
will only fire if that zone happens to be running on the CPU on which
the tick probe fires.  This breaks many scripts that (naturally) use
tick probes as a kind of local timeout mechanism.  For us at Joyent,
this has become a top annoyance for our customers who themselves want
to use DTrace from within the zone, so we wanted to take a swing at
addressing this -- but we also needed to be mindful (obviously) of not
allowing privilege escalation.  Complicating things, I also wanted to
do this in a way that preserves the existing behavior for the profile
probes:  that they don't fire when in a context that one cannot
execute is actually the easiest way of assuring that a profile-based
enabling in the non-global zone does (roughly) what the user thinks it
does.  So the model we came to is to split the behavior (slightly) of
the profile provider, and use the provider's dtps_usermode (which I
have renamed to dtps_mode) to inform as to both mode (kernel mode v.
user mode) and policy (if the user cannot execute in this context,
this firing should be dropped v. restricted).  When restricted, the
user does not have either proc privileges, nor the privileges
necessary to examine arguments, and attempts to do so will induce a
UPRIV or KPRIV fault (respectively).  From the (new) block comment
explaining the dtps_mode entry point, the return value from dpts_mode
  A bitwise OR that encapsulates both the mode (either DTRACE_MODE_KERNEL
  or DTRACE_MODE_USER) and the policy when the privilege of the enabling
  is insufficient for that mode (either DTRACE_MODE_NOPRIV_DROP or
  DTRACE_MODE_NOPRIV_RESTRICT).  If the policy is DTRACE_MODE_NOPRIV_DROP,
  insufficient privilege will result in the probe firing being silently
  ignored for the enabling; if the policy is DTRACE_NODE_NOPRIV_RESTRICT,
  insufficient privilege will not prevent probe processing for the
  enabling, but restrictions will be in place that induce a UPRIV fault
  upon attempt to examine probe arguments or current process state.
Attached is a patch that implements this.  I have integrated this into
our bits at Joyent (internal ticket is OS-431, "dtrace profile and
tick probes sometimes don't fire in a zone"), so -- as with our other
work -- you'll see this show up soon (next two weeks or so) at
http://github.com/joyent/illumos-joyent, but I wanted to give folks an
earlier heads-up in case we want to have further discussion here.  In
particular:  Adam, it would be great if you could take a look at this
at some point -- though I would obviously welcome anyone else's
feedback as well!
       - Bryan
_______________________________________________
Developer mailing list
http://lists.illumos.org/m/listinfo/developer
--
Adam Leventhal, Delphix
http://dtrace.org/blogs/ahl

275 Middlefield Road, Suite 50
Menlo Park, CA 94025
http://www.delphix.com
Loading...