crash handlers and PTRACE in Ubuntu 10.10

Kees Cook kees at ubuntu.com
Wed Jun 23 07:06:00 BST 2010


Hi,

(Jonathan, Philip, I've added you to CC explicitly so we're all in the
same thread here instead of splitting between here and the KDE bug.)

On Mon, Jun 21, 2010 at 08:14:46PM +0800, John McCabe-Dansted wrote:
> On Mon, May 31, 2010 at 1:03 PM, Kees Cook <kees at ubuntu.com> wrote:
> >  a) Using "strace -p PID" and gdb's "attach" command will NOT work
> >    unless you are the root user (i.e. use "sudo strace -p PID ...")
> >    Running stuff with "strace" and "gdb" directly will work normally.
> ...
> >  a) /proc/sys/kernel/ptrace_scope: "0" allows original ptrace behavior
> ...
> > I expect that the PTRACE changes will cause the greatest surprise.  Since
> > PTRACE is rarely needed by normal users, this change makes sense for the
> 
> I imagine that this will break software that does something like
> 
> onAssert() {
>    echo bt | gdb -q $0 getpid()
>    Alert ("Please report this backtrace", "Continue?") || die
> }
> 
> Am I correct, if so what preferred technique should we replace this with?
> 
> The best simple solution I can see is something like
> 
> if (child_pid=fork()) {
>    //parent
>    wait(child_pid,...);
>    //process core file here
> } else {
>    abort();
> }
> 
> However this doesn't seem as nice, we have to unblock core dumps using
> ulimit, we have to actually have to have space for the core dumps.
> Also we have to assume that the core file generated matches "core*"
> which theoretically may not be the case. If this is the best we can do
> it is probably still better than automatically setting setting system
> wide security configurations such as  ``/proc/sys/kernel/ptrace_scope:
> "0"'' in the installer.

So we have a problem here that we need to find a solution to.  Both KDE[1]
in general, and Chromium[2] in particular have their own crash handlers
that currently depend on being able to spawn a debugger against the
crashing process (as a sibling or cousin of the crashing process).

I see at least a few ways to handle this:

1) "pre-spawn"
   Have applications reworked to pre-spawn a process that is the crash
   handler.  This does not work for KDE, though, since it it spawns gdb
   for a series of commands instead of doing its own PTRACE-based
   manipulation.

2) "manual sysctl"
   Have anyone interested in native application crash handlers set
   0 to /proc/sys/kernel/ptrace_scope manually.  This means that crashes
   from non-developers are not reported.

3) "packaged sysctl"
   When KDE or Chromium are installed, ship a file in /etc/sysctl.d/
   that sets 0 to /proc/sys/kernel/ptrace_scope.  This weakens the
   system over all, and isn't much better than just changing the default
   everywhere.

4) "Apport hooks"
   Recognize that the goal is to have _crash_ handlers.  There doesn't
   appear to be a need to actually be running PTRACE on the crashed
   process -- it's just a report of the state of the process and access
   to its memory -- all possible through the coredump.  So, have
   applications register a hook with Apport to handle coredumps since
   Apport already has all the built-in logic to handle core dumps without
   messing with ulimits, etc.  This becomes useless if Apport is not
   running, and Apport does not run during the stable release.  (Though
   maybe Apport could be improved to handle this more gracefully?)

5) "declared PTRACEing"
   Recognize that the PTRACEing we want to allow is in very specific
   declared situations (i.e. the PID of the debugger is always known by
   the debugee, so have the debugee "declare" that it wishes to be
   debugged).  This interface does not exist.  It would require the
   creation of something like:
        ptrace(PTRACE_TRACEDBY, debugger_pid, NULL, NULL);
   This would be, at least for now, an Ubuntu-specific extension.  For
   KDE applications, this is a trivial change, since the KDE crash
   handler stays in a while loop, calling sleep() until the debugger
   process quits.  Chromium would likely need to pass the debugger pid
   back through the segfault handler in the sandbox -- I got lost reading
   the syscall emulation-through-seccomp, so maybe it's as easy as KDE's.

6) "new kernel heuristic"
   Find a different heuristic that could apply in these crash cases that
   would not be vulnerable to the process-hijacking attacks that the
   PTRACE restrictions are seeking to block.  This is tricky since the
   crashed processes are usually blocked (but not dead) in their segv
   handler, so the process isn't strictly _dead_, so I haven't been able
   to think up ways that such a process is distinguishable from a normal
   process by the kernel.

7) "disable by default"
   Leave the ability to restrict PTRACE, but leave it set to "0".  This
   leaves Ubuntu users at large vulnerable to a class of process-hijacking
   attacks that worms could use, except for those that want to set it to
   "1", like can be done with the module-loading blocker[3].


I prefer 4 (Apport hooks), as it would leverage existing code and actually
eliminates PTRACE completely.  Option 5 (declared PTRACEing) is second,
but puts Ubuntu is a weird spot with regard to the upstream kernel which
hasn't been too happy about the idea of mucking with existing PTRACE
interfaces.  Option 6 (new kernel heuristic) would be really great,
but it doesn't current have an implementation and I worry it would be
fragile.  I'd go for 3 ("packaged sysctl settings") before 7 ("disable
by default"), though it seems poor since lots of system will end up in
the more vulnerable state.  I don't think 1 ("pre-spawn") is workable,
but I may just lack imagination (maybe some combination/variation of 1
and 6 that worked out).  And 2 ("manual sysctl") doesn't really address
the larger desire of upstreams wanting crash feedback.

Thoughts?

-Kees

[1] https://launchpad.net/bugs/589841
[2] http://code.google.com/p/chromium/issues/detail?id=46368
[3] http://www.outflux.net/blog/archives/2009/07/31/blocking-module-loading/


-- 
Kees Cook
Ubuntu Security Team



More information about the ubuntu-devel mailing list