OpenSolaris

Printable Version Enter a New Search
Bug ID 6393431
Synopsis dtrace_proc + proc_owner doesn't sufficiently enable destructive actions
State 10-Fix Delivered (Fix available in build)
Category:Subcategory kernel:dtrace
Keywords onnv_triage
Responsible Engineer Daniel Price
Reported Against
Duplicate Of
Introduced In
Commit to Fix snv_37
Fixed In snv_37
Release Fixed solaris_nevada(snv_37) , solaris_10u4(s10u4_03) (Bug ID:2144471)
Related Bugs 4970596
Submit Date 3-March-2006
Last Update Date 16-February-2007
Description
In testing some dtrace changes, I discovered a puzzling behavior which
I think may be a bug.  Feel free to close this report if DTrace is doing
the right thing, and I'm confused.  Otherwise, I think I can fix this
problem.

The problem I'm seeing comes in a configuration with two user accounts,
like this.  "poweruser" is granted proc_owner, which gives scope to
muck with all processes (in this zone).  "poweruser" is also granted
dtrace_proc, the privilege to use pid and fasttrap DTrace providers.

$ uname -a
SunOS snowdog 5.11 snv_31 sun4u sparc SUNW,Sun-Blade-2500

poweruser $ ppriv $$
6459:   /usr/bin/tcsh
flags = <none>
        E: basic,dtrace_proc,proc_owner
        I: basic,dtrace_proc,proc_owner
        P: basic,dtrace_proc,proc_owner
        L: all
poweruser $ id
uid=1000(poweruser) gid=10(staff)

Now, poweruser tries to operate on processes which are run by
a user account 'victim', configured like this:

victim $ ppriv $$
6169:   -bash
flags = <none>
        E: basic,dtrace_proc
        I: basic,dtrace_proc
        P: basic,dtrace_proc
        L: all
victim $ id
uid=2000(victim) gid=10(staff)

Here is what I observe:

      - 'victim' can pstop and prun 'victim'.

      - 'victim' can use the pid provider to trace 'victim':

        victim $ dtrace -n pid6169::read:entry
        dtrace: description 'pid6169::read:entry' matched 1 probe
        CPU     ID                    FUNCTION:NAME
          0  52270                       read:entry 
          1  52270                       read:entry 

      - 'victim' can use destructive actions against 'victim':

        victim $ dtrace -w -n \
           pid6169::read:entry'{raise(20); printf("WINCHed victim");}'
        dtrace: description 'pid6169::read:entry' matched 1 probe
        dtrace: allowing destructive actions
        CPU     ID                    FUNCTION:NAME
          1  52270                       read:entry WINCHed victim
          1  52270                       read:entry WINCHed victim

      - 'poweruser' can use pstop and prun against 'victim'.

      - 'poweruser' can use the pid provider to trace 'victim':

        poweruser $ dtrace -n pid6169::read:entry
        dtrace: description 'pid6169::read:entry' matched 1 probe
        CPU     ID                    FUNCTION:NAME
          1  52270                       read:entry 
          0  52270                       read:entry 

bug?  - 'poweruser' *cannot* use destructive actions against 'victim':

        poweruser $ dtrace -w -n \
            pid6169::read:entry'{raise(20); printf("WINCHed victim");}'
        dtrace: description 'pid6169::read:entry' matched 1 probe
        dtrace: allowing destructive actions
        dtrace: error on enabled probe ID 1 (ID 52270: pid6169:libc.so.1:read:entry): invalid user access in action #1
        dtrace: error on enabled probe ID 1 (ID 52270: pid6169:libc.so.1:read:entry): invalid user access in action #1


The DTrace guide suggests (although doesn't state explicitly) in its
dtrace_proc table that dtrace_proc + proc_owner should be sufficient
to allow destructive actions against other processes.  I used MDB to
check that the victim (just a 'bash' shell) was in no way unusual
from the perspective of its credentials; that is to say, for this
process gid == rgid == sgid  and  uid == ruid == suid  and SNOCD is
*not* set in p_flag.   Any of these might trigger additional priv
checking if not true.

I think the fix here is that dtrace_state_create() needs a clause
which activates DTRACE_CRA_PROC_DESTRUCTIVE in the event that dtrace_proc
and proc_owner are both held by the debugging process ("poweruser")
in this case.  To me, it intuitively makes sense that if you can
trace a process, you should also be able to raise() or stop() it.

Now please excuse me while my head explodes.
Work Around
N/A
Comments
N/A