Wednesday, May 15, 2013

Linux PERF_EVENTS root exploit - CVE-2013-2094 (quick way to fix it)

Recently a quite critical flaw has been found in the PERF_EVENT code in Linux.

The problem is a failure at checking a 64-bits variable (cast to a 32-bits int) passed by user space, resulting to out-of-bounds access of an array in kernel space.

Here is the exploit: http://packetstormsecurity.com/files/121616/semtex.c

The bug has been already fixed mainstream: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8176cced706b5e5d15887584150764894e94e02f

But lots of distro kernels are affected by this bug, so they're vulnerable to the root exploit (like all the RH / CentOS 2.6.32-based kernels).

A temporary solution, waiting for a new kernel to come out, can be to create a kernel module to "inject" the fix into the kernel at runtime, using the kprobe framework.

Here is the source code of the module:
https://www.develer.com/~arighi/linux/fix/CVE-2013-2094/perf-bug-fix.tar.gz

This module injects the fix by wrapping the buggy function perf_swevent_init() using the kprobe framework.

This would allow to provide a fix really soon, and it works with any kernel affected by this bug.

To compile it (on CentOS - instructions are almost identical in other distro):

  $ sudo yum install kernel-devel
  $ tar xvzf perf-bug-fix.tar.gz
  $ cd perf-bug-fix
  $ make

How to load the module and apply the fix:

 $ sudo insmod wrapper.ko

That's it. Now let's test the exploit.

Without wrapper.ko loaded:

cpuser1@testdomain1.com [/dev/shm]# id -u
521
cpuser1@testdomain1.com [/dev/shm]# ./a.out
...
 -sh-4.1# id -u
0

With wrapper.ko:

cpuser1@testdomain1.com [/dev/shm]# ./a.out
a.out: test.c:51: sheep: Assertion `!close(fd)' failed.
Aborted (core dumped)
cpuser1@testdomain1.com [/dev/shm]# id -u
521

4 comments:

Andrea Righi said...

BTW, I didn't mention it explicitly, but this can be also considered as a zero downtime update, since there's no need to reboot the kernel. Just insert the module and the fix is applied immediately at run-time.

Obviously this is just a workaround, the solution is to update the kernel, but at least we can be safe against this attack and avoid to schedule a downtime as soon as possible.

Kim Twain said...

Thanks a lot! I was waiting for a kernel update from debian, but it hasn't been released yet. Smart and easy way to "fix" the bug (on redhat's bugzilla they were suggesting to use systemtap)

Andrea Righi said...

Yes, this is almost the same as the systemtap solution. But in this way you don't need to install the whole systemtap stuff.

Walid Shaari said...

Great, I wish i have seen that earlier. in my situation i am stuck with a specific kernel so that would have worked the best. due to solution dependencies i can not upgrade the kernel and redhat mitigation workaround were fine, but that is much better.