xorl %eax, %eax

Linux kernel PTrace Race Condition

with 10 comments

This issue was reported on 26 April 2009 by Oleg Nesterov of Red Hat and affects Linux kernel up to 2.6.29 release. The vulnerability is located in ptrace_attach() routine of kernel/ptrace.c. Here is some code as seen in 2.6.29 release:

175 int ptrace_attach(struct task_struct *task)
176 {
177        int retval;
178        unsigned long flags;
179
180        audit_ptrace(task);
181
182        retval = -EPERM;
183        if (same_thread_group(task, current))
184                goto out;
185
186        /* Protect exec's credential calculations against our interference;
187         * SUID, SGID and LSM creds get determined differently under ptrace.
188         */
189        retval = mutex_lock_interruptible(&current->cred_exec_mutex);
190        if (retval  < 0)
191                goto out;
192
193        retval = -EPERM;
194 repeat:
       ...
230 bad:
231        write_unlock_irqrestore(&tasklist_lock, flags);
232        task_unlock(task);
233        mutex_unlock(&current->cred_exec_mutex);
234 out:
235        return retval;
236 }

Eugene Teo quickly noticed the potential vulnerability in this code. As you can see at lines 189 and 233, ptrace_attach() uses the current process’ MUTEX to lock and serialize the two tasks (the current one, and the one passed to that function as an argument). However, the above code incorrectly uses the current task’s cred_exec_mutex instead of the task’s to be traced. This creates a race condition which allows a user to ptrace(PTRACE_ATTACH) during the execution of an execve() call to a SUID binary. But this new member (cred_exec_mutex) was added to the task_struct to avoid exactly this behavior as you can read at include/linux/sched.h:

1114 struct task_struct {
       ...
1245        struct mutex cred_exec_mutex;   /* execve vs ptrace cred calculation mutex */
       ...
1420 };

This can lead to local privilege escalation and the patch was to change the MUTEX locks accordingly like this:

         */
-       retval = mutex_lock_interruptible(&current->cred_exec_mutex);
+       retval = mutex_lock_interruptible(&task->cred_exec_mutex);
        if (retval  < 0)

And:

        task_unlock(task);
-       mutex_unlock(&current->cred_exec_mutex);
+       mutex_unlock(&task->cred_exec_mutex);
 out:

Written by xorl

May 8, 2009 at 10:38

Posted in bugs, linux

10 Responses

Subscribe to comments with RSS.

  1. hi i don’t konw if i really good thinging about id. So we can ptrace_attach suid process and change this process(e.g. ptrace(PTARACE_POKETEXT) to put shellcode and execute?

    md

    May 10, 2009 at 15:24

  2. You can PTRACE_ATTACH to a process during an execve() call to a SUID binary since the race window is open during the incorrect MUTEX locks only.

    xorl

    May 10, 2009 at 15:53

  3. so what can i make with one suid proces when is ptraced? Sorry 4 this questions but i don’t have kernel 29 and i can’t test this.

    md

    May 10, 2009 at 17:57

  4. Unfortunately md, as I have stated numerous times, this blog will not provide any knowledge beyond the already known information about the vulnerabilities discussed. Consequently, I cannot give further details regarding the exploitation.
    You may have noticed that the vuln. analysis I post do not have any exploitation sections. I’m sorry.

    xorl

    May 10, 2009 at 18:18

  5. Ok I understand. Thanks.

    md

    May 10, 2009 at 18:27

  6. it`s a pretty slim race , and it would be best to get it right in one shot, before caches start to work … :)

    ea

    May 14, 2009 at 20:27

  7. :D
    That’s exactly my problem with this race! I was discussing this with various people after noticing it. It would be pretty nice if you could somehow find information that would let you know when the execution has reached the mutex or any other important point(s) (it would be even better if you can control some of them :P). I still haven’t found anything though.

    In addition, both public exploits don’t use anything to increase reliability. prdelka’s (http://milw0rm.com/exploits/8678) perfroms a check through procfs but nothing really important in my opinion. As you have already said, the re-tries can result in cache memory access and it could take some time to get any results by just brute-forcing. :)

    xorl

    May 14, 2009 at 22:07

  8. What kernel versions are vulnerable? Are we talking the entire 2.6 branch?

    Cheers

    Jonas Malmgren

    May 16, 2009 at 05:56

  9. Jonas i think 2.6.29

    md

    May 19, 2009 at 05:10

  10. Jonas Malmgren sorry for the delayed reply, md is correct. This affects only 2.6.29 through 2.6.29.2 kernels since cred_exec_mutex was introduced in 2.6.29 to ptrace’s code and in 2.6.29.3 the bug was patched.

    xorl

    May 19, 2009 at 14:38


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s