xorl %eax, %eax

Linux kernel KVM CR8 Register NULL Pointer Dereference

leave a comment »

Another neat email I saw yesterday on oss-security was this one. This is for a bug discovered by Avi Kivity of Red Hat that affects releases prior to 2.6.32-rc1. Here is some code from 2.6.31 release of the Linux kernel…

static void update_cr8_intercept(struct kvm_vcpu *vcpu)
{
        int max_irr, tpr;

        if (!kvm_x86_ops->update_cr8_intercept)
                return;

        if (!vcpu->arch.apic->vapic_addr)
                max_irr = kvm_lapic_find_highest_irr(vcpu);
        else
                max_irr = -1;

        if (max_irr != -1)
                max_irr >>= 4;

        tpr = kvm_lapic_get_cr8(vcpu);

        kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr);
}

This tiny utility routine is used to update CR8 (Control Register 8). CR8 register, also known as TPR (Task Priority Register) is used widely in virtualization systems. Specifically, it’s part of the APIC (Advanced Programmable Interrupt Controller) of Intel processors. The problem with update_cr8_intercept() function is that it attempts to access ‘vcpu->arch.apic->vapic_addr’ before calling kvm_lapic_find_highest_irr() to ensure that it doesn’t contain a NULL value. However, if there is no APIC present, ‘vcpu->arch.apic’ pointer would be NULL and the request to access the ‘vapic_addr’ member would result in a NULL pointer dereference.
The fix was of course…

        if (!kvm_x86_ops->update_cr8_intercept)
                return;
 
+       if (!vcpu->arch.apic)
+               return;
+
        if (!vcpu->arch.apic->vapic_addr)

At last, Eugene Teo noted in his email to oss-security, that it can be triggered through kvm_vcpu_ioctl() IOCTL handling routine of KVM on the /dev/kvm device file.

Written by xorl

October 24, 2009 at 12:25

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