xorl %eax, %eax

CVE-2009-0029: Linux kernel 64bit ABI Signedness Issue

leave a comment »

This bug was reported by Christian Borntraeger of IBM on 13 Februrary 2009 and affects Linux kernel prior to 2.6.28.6 on s390, PowerPC,
Sparc64, and MIPS 64-bit platforms. This vulnerability was a simple signedness issue on some 64-bit architectures that require sign extension on function parameters. Eugene Teo gave an excellent example of this behavior like this:

asmlinkage long sys_example(unsigned int index)
{
        if (index > 5)
                return -EINVAL;
        return example_array[index];
}

This code is perfectly correct on 32-bit and some 64-bit architectures but on the previously mentioned it will cause an error. Variable index will be checked as a 32-bit unsigned integer in the if statement but the memory access will be on 64-bit mode. Meaning, that it might lead to arbitrary memory access since the if condition will completely ignore the higher 32-bits of index integer. To fix this, Linux kernel developers wrote a collection of system call wrapper macros which update the scopes of the system calls accordingly. For example, this system call:

asmlinkage long sys_getcwd(char __user *buf, unsigned long size)

Was replaced like this:

SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)

This macro can be found at arch/sparc64/kernel/sys_sparc.c for Sparc64 and it does this:

672 SYSCALL_DEFINE2(getdomainname, char __user *, name, int, len)
673 {
674        int nlen, err;
675
676        if (len < 0)
677                return -EINVAL;
678
679        down_read(&uts_sem);
680        
681        nlen = strlen(utsname()->domainname) + 1;
682        err = -EINVAL;
683        if (nlen > len)
684                goto out;
685
686        err = -EFAULT;
687        if (!copy_to_user(name, utsname()->domainname, nlen))
688                err = 0;
689
690 out:
691        up_read(&uts_sem);
692        return err;
693 }


This performs the appropriate checks for the integer values passed to it. That’s all with this bug. Obviously, many system calls can lead to code execution since you can bypass various checks because of this missing sign extension.

Written by xorl

April 8, 2009 at 17:58

Posted in bugs, linux

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