Disabling ptrace

Konstantin Belousov kostikbel at gmail.com
Fri Jan 2 17:13:22 UTC 2015


On Fri, Jan 02, 2015 at 09:16:42AM +0000, Robert Watson wrote:
> On Tue, 30 Dec 2014, Konstantin Belousov wrote:
> 
> > The question about a facility to disable introspection functionality (ptrace 
> > etc) for a process was asked several times. The latest query made me 
> > actually code the feature. Note that other systems, e.g. Linux and OSX, do 
> > have similar facilities.
> >
> > Patch is below, it provides two new procctl(2) requests.  PROC_TRACE_ENABLE 
> > enables or disables tracing.  It includes core dumping, ptrace, ktrace, 
> > debugging sysctls and hwpmc.  PROC_TRACE_STATUS allows to get the tracing 
> > state.
> >
> > Most interesting question is how should disabling of trace behave with 
> > regard of fork and exec. IMO, the right model is to protect access to the 
> > _program_ address space, which translates to inheritance of the attribute 
> > for fork, and reenabling the tracing on exec. On the other hand, I 
> > understand that some users want to inherit the tracing disable on exec, so 
> > there are PROC_TRACE_SET_DISABLED and PROC_TRACE_SET_DISABLED_EXEC, the 
> > later makes disable to be kept after exec.
> >
> > Note that it is trivial for root on the host to circumvent the feature.
> 
> I admit some curiosity about the use case as well -- if this is a security 
> feature, possibly this should be a property of the credential rather than the 
> process?  Among other things, this could help implement trace limitations in 
> asynchronous contexts -- not that I'm aware of too many currently, but if 
> you don't want the I/O of a program traced in the synchronous context, I 
> guess it might follow that you wouldn't want that to happen asynchronously 
> either (etc).
> 
> On the other hand, if this is a security feature, it doesn't really 'stand 
> alone' very well, as in absence of a more complete policy, simply disabling 
> introspection features doesn't provide guarantees, just annoyance until 
> someone writes a suitable script to work around it.  This has been one of my 
> objections to securelevel, FWIW: while the various bits building it are useful 
> for admins (e.g., file flages), securelevel isn't a 'coherent' policy that 
> gives you strong integrity properties, rather, a set of manual frobs and 
> inconsistent design choices that mean it's very hard to imagine an admin ever 
> getting it to be useful without running with read-only filesystems, etc (and 
> even then).
> 
> In MAC policies such as Biba and MLS, we mediate the ability to debug target 
> processes based on additional labels, but there framing integrity and 
> confidentiality policies give the restriction a security context.  In the Mac 
> OS X version of the MAC Framework, support for disabling debugging following 
> execve() is slightly more mature in FreeBSD: in FreeBSD it's done based on 
> label change (a la credential change), but in Mac OS X it tracks a policy 
> entry point that decides whether the change has access-control significance 
> (which means you can have information-flow tracking policies that manipulate 
> labels but don't change functional aspects of the system, which isn't possible 
> in the FreeBSD version currently).  There's a good argument we should pick up 
> the Mac OS X design choice there at some point.
> 
> The reason I wonder about the use case is actually one to do with accurate 
> performance debugging of systems: ssh, ssh-agent, and friends can already 
> request that they not be core dumped to avoid leaking keying material to 
> filesystems, but having them be exempt from hwpmc, DTrace, etc, will make 
> understanding system and application behaviour harder -- and if they 'fail 
> silently' then users could suffer potentially confusing (and misleading) 
> results.  Is the general concern here that people are turning on 
> tracing/profiling/etc tools and not understanding that they may be leaking 
> keying material?
> 
> (Note that we do have a global safety frob to disable ptrace and friends 
> systemically, security.bsd.unprivileged_proc_debug, which is intended as an 
> easily available workaround for security vulnerabilities discovered in 
> process-debugging facilities, which have historically proven a bit 
> vulnerability-prone across all operating systems I'm aware of.  We should 
> remember this next time we cut an advisory on a ptrace/ktrace/ec 
> vulnerability.)

Use case does not have anything with security. It is obfuscation and
making the introspection harder, for some dynamic scope. AFAIU, it
is the same as the usage of the similar facilities in Linux and OSX.
Everybody involved in conversation understood the inherit limitations
of the reliability of the knob. It is usual cost of implementing vs.
cost of breaking protection scheme. and since exactly this bit of
reverse-engineering defense is asked for many times, I do not see
it much wrong in falling into conformity with other OSes.

I did not intended the PROC_TRACE_ENABLE applied to the programs
manipulating the keying material.  I do not see any 'protection'
the ban could add there,  user already posses an access to his
own keys.  Even if you mean access to the temporal session keys, generated
by for the conversation instance, as opposed to the private key material
used to establish sessions, I do not see why would system need to
actively prevent user from gaining access to it.  Inter-credential
barriers must provide adequate separation.

I should note that I very much dislike Ubuntu-style vandalization of
the ptrace(2) API.  AFAIK, it only allows PT_ATTACH to the (indirect)
child of the debugger.

WRT putting the trace-disabled indicator into the credentials, instead
of just having it as a process attribute, I am not sure that this is
useful thing.  Do you propose to modify existing ucred for the process,
effectively applying the notrace policy to the whole set of processes
sharing the credential, or do COW for ucred on disable ?  If not COW,
then the set of the affected processes is somewhat random and too wide.
If COW, I do not see much practical difference with the per-process
bit, esp. due to the execve(2) handling.

Also, I am puzzled by reference to an async context.
Could you provide explicit examples where we do such tracing ?


More information about the freebsd-arch mailing list