[CVE-2012-1601] Hardy fixes

Herton Ronaldo Krzesinski herton.krzesinski at canonical.com
Fri Jun 29 16:32:00 UTC 2012


Hi,

this is a revisit of CVE-2012-1601 for Hardy. Actually, in the course of
doing some tests, other problems were discovered with kvm on x86, so
some of the fixes may not be directly related to the core issue in
CVE-2012-1601, but similar test case exploiting the issue hit the
problems. Thus, I marked all patches for this CVE. The extra fixes are
needed for Hardy only.

It took me a while this week to revisit this, and I tested with i386 and
amd64 hardy installs on an Intel processor with vmx (Core2 quad Q6000).
I don't have any AMD based machine to verify things, but the fixes
doesn't touch svm or vmx directly, the memory corruption issue does take
specific paths for vmx/svm, but should still trigger problems with both,
and shouldn't make a difference. But anyone willing to run kvm on hardy
and having an AMD machine is welcome if wants to test this series.

So lets go to the series of patches:

The first patch, "KVM: MMU: nuke shadowed pgtable pages and ptes on
memslot destruction", is just required infra-structure by the second patch.

The second patch, "KVM: MMU: do not free active mmu pages in
free_mmu_pages()", addresses the following oops, possible with a
specially crafted test program:

[   76.644928] BUG: unable to handle kernel paging request at virtual address 00001594
[   76.644933] printing eip: f8b1434e *pde = 00000000
[   76.644937] Oops: 0000 [#1] SMP
[   76.644940] Modules linked in: ipv6 af_packet rfcomm l2cap bluetooth ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 xt_state nf_conntrack ipt_REJECT xt_tcpudp bridge kvm_intel kvm ppdev acpi_cpufreq cpufreq_ondemand cpufreq_userspace cpufreq_stats freq_table cpufreq_conservative cpufreq_powersave container video output dock sbs sbshc battery iptable_filter ip_tables x_tables ac parport_pc lp parport snd_hda_intel snd_pcm_oss snd_mixer_oss snd_pcm snd_page_alloc snd_hwdep snd_seq_dummy snd_seq_oss snd_seq_midi snd_rawmidi iTCO_wdt atl1c iTCO_vendor_support snd_seq_midi_event serio_raw compat snd_seq led_class snd_timer pcmcia_core snd_seq_device snd button psmouse pcspkr evdev shpchp pci_hotplug soundcore ext3 jbd mbcache sg sr_mod cdrom sd_mod pata_acpi ata_generic ata_piix libata floppy scsi_mod ehci_hcd uhci_hcd usbcore thermal processor fan fbcon tileblit font bitblit softcursor fuse
[   76.644988]
[   76.644990] Pid: 6072, comm: test Not tainted (2.6.24-31-generic #1)
[   76.644993] EIP: 0060:[<f8b1434e>] EFLAGS: 00010246 CPU: 1
[   76.645005] EIP is at free_mmu_pages+0xe/0x30 [kvm]
[   76.645007] EAX: f6942000 EBX: f6942000 ECX: 00000000 EDX: 00000000
[   76.645009] ESI: f6942000 EDI: f694e000 EBP: 00000000 ESP: f693fee0
[   76.645011]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
[   76.645013] Process test (pid: 6072, ti=f693e000 task=f6941700 task.ti=f693e000)
[   76.645014] Stack: f6942000 f8b1437f f6942000 f8b0f0cf f6942000 f8b0d6e8 f6942000 f8af505d
[   76.645020]        f8b0d783 f6942000 f8b0eeb1 fffffff4 f8b0d5f3 f6fa9088 f7402a80 00000004
[   76.645025]        c01becea f693ff58 f693ff5c 00000000 00000006 f8b1f9d3 f694e000 f694e000
[   76.645029] Call Trace:
[   76.645036]  [<f8b1437f>] kvm_mmu_destroy+0xf/0x60 [kvm]
[   76.645050]  [<f8b0f0cf>] kvm_arch_vcpu_uninit+0xf/0x20 [kvm]
[   76.645063]  [<f8b0d6e8>] kvm_vcpu_uninit+0x8/0x20 [kvm]
[   76.645076]  [<f8af505d>] vmx_free_vcpu+0x7d/0x90 [kvm_intel]
[   76.645081]  [<f8b0d783>] vcpu_put+0x13/0x20 [kvm]
[   76.645095]  [<f8b0eeb1>] kvm_arch_vcpu_destroy+0x21/0x30 [kvm]
[   76.645107]  [<f8b0d5f3>] kvm_vm_ioctl+0x103/0x1c0 [kvm]
[   76.645120]  [<c01becea>] anon_inode_getfd+0x10a/0x150
[   76.645129]  [<f8b0c4ec>] kvm_dev_ioctl+0x13c/0x180 [kvm]
[   76.645141]  [<f8b0d4f0>] kvm_vm_ioctl+0x0/0x1c0 [kvm]
[   76.645153]  [<c019e5db>] do_ioctl+0x2b/0x90
[   76.645159]  [<c019e86e>] vfs_ioctl+0x22e/0x2b0
[   76.645163]  [<c019060e>] do_sys_open+0xbe/0xe0
[   76.645168]  [<c019e946>] sys_ioctl+0x56/0x70
[   76.645173]  [<c01043b2>] sysenter_past_esp+0x6b/0xa9
[   76.645182]  =======================
[   76.645183] Code: 00 5b 5e 5f c3 29 c8 01 f8 89 86 88 05 00 00 89 be 90 05 00 00 5b 5e 5f c3 8d 74 26 00 53 89 c3 eb 07 89 c8 e8 54 fb ff ff 8b 0b <8b> 91 94 15 00 00 8d 81 94 15 00 00 39 c2 75 e7 8b 83 b4 01 00
[   76.645209] EIP: [<f8b1434e>] free_mmu_pages+0xe/0x30 [kvm] SS:ESP 0068:f693fee0
[   76.645221] ---[ end trace 3aba90d300d74238 ]---

The third patch, "KVM: Don't destroy vcpu in case vcpu_setup fails",
fixes a memory corruption issue on x86 if kvm_arch_vcpu_setup fails.
When it fails, a double call of kvm_x86_ops->vcpu_free(vcpu) is done,
first inside kvm_arch_vcpu_setup error handler (free_vcpu label), and
again inside kvm_vm_ioctl_create_vcpu: when kvm_arch_vcpu_setup fails,
it goes to vcpu_destroy error handling, calling kvm_arch_vcpu_destroy.
kvm_arch_vcpu_destroy on arch/x86/kvm/x86.c also calls
kvm_x86_ops->vcpu_free(vcpu), meaning double free of some structures.
Thus after running the test program, you may start to see in kernel log
"Bad page state in process" messages. slub_debug catches the corruption,
this is the trace which helped getting to the root of the problem:

[  275.461857] invalid opcode: 0000 [#1] SMP 
<?>[  275.461951] Modules linked in: netconsole configfs ipv6 af_packet rfcomm l2cap bluetooth ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 xt_state nf_conntrack ipt_REJECT xt_tcpudp bridge kvm_intel kvm ppdev acpi_cpufreq cpufreq_ondemand cpufreq_userspace cpufreq_stats freq_table cpufreq_conservative cpufreq_powersave container video output dock sbs sbshc battery iptable_filter ip_tables x_tables ac parport_pc lp parport iTCO_wdt iTCO_vendor_support atl1c compat led_class serio_raw pcmcia_core evdev button shpchp pci_hotplug psmouse pcspkr ext3 jbd mbcache sg sr_mod cdrom sd_mod pata_acpi ata_generic ata_piix libata scsi_mod floppy ehci_hcd uhci_hcd usbcore thermal processor fan fuse vesafb fbcon tileblit font bitblit softcursor[  275.463960] Process test2 (pid: 5962, ti=f69a8000 task=f6818000 task.ti=f69a8000)
[  275.464007] Stack: 00000419 c018d562 00000000 c16eef60 c03f8700 c16ed9a0 f8c8215b 00006b6b 
[  275.464265]        00000000 00000000 00000000 ab6b6b6b 00000000 f8c8215b f761a000 f761a000 
[  275.464522]        f751c000 00000000 f8c82d6c f761a000 f8c81ec8 fffffff4 f8c80613 f6d18210 
[  275.464780] Call Trace:
[  275.464858]  [<c018d562>] __slab_free+0x202/0x2a0
[  275.464928]  [<f8c8215b>] kvm_arch_vcpu_setup+0x4b/0x60 [kvm]
[  275.465007]  [<f8c8215b>] kvm_arch_vcpu_setup+0x4b/0x60 [kvm]
[  275.465087]  [<f8c82d6c>] kvm_arch_vcpu_load+0xc/0x20 [kvm]
[  275.465163]  [<f8c81ec8>] kvm_arch_vcpu_destroy+0x8/0x30 [kvm]
[  275.465240]  [<f8c80613>] kvm_vm_ioctl+0x103/0x1c0 [kvm]
[  275.465320]  [<c01becea>] anon_inode_getfd+0x10a/0x150
[  275.465987]  [<f8c7f4ec>] kvm_dev_ioctl+0x13c/0x180 [kvm]
[  275.466062]  [<f8c80510>] kvm_vm_ioctl+0x0/0x1c0 [kvm]
[  275.466136]  [<c019e5db>] do_ioctl+0x2b/0x90
[  275.466206]  [<c019e86e>] vfs_ioctl+0x22e/0x2b0
[  275.466272]  [<c019060e>] do_sys_open+0xbe/0xe0
[  275.466338]  [<c019e946>] sys_ioctl+0x56/0x70
[  275.466404]  [<c01043b2>] sysenter_past_esp+0x6b/0xa9
[  275.466481]  =======================
[  275.466521] Code: 44 24 1c b9 01 00 00 00 c7 44 24 1e 00 00 00 00 8d 44 24 1c 66 c7 44 24 22 00 00 c7 44 24 24 00 00 00 00 c7 44 24 28 00 00 00 00 <66> 0f 38 81 08 77 02 0f 0b 8b 95 30 10 00 00 e9 c4 fe ff ff 8b 
[  275.468037] EIP: [<f8c67f8d>] vmx_vcpu_load+0x17d/0x1c0 [kvm_intel] SS:ESP 0068:f69a9eb8
[  275.468605] ---[ end trace c5cafd565f057c9f ]---
[  275.468704] BUG: unable to handle kernel paging request at virtual address 6b6b6b6f
[  275.468787] printing eip: c031c18d *pde = 00000000 
[  275.468873] Oops: 0000 [#2] SMP 
<?>[  275.468956] Modules linked in: netconsole configfs ipv6 af_packet rfcomm l2cap bluetooth ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 xt_state nf_conntrack ipt_REJECT xt_tcpudp bridge kvm_intel kvm ppdev acpi_cpufreq cpufreq_ondemand cpufreq_userspace cpufreq_stats freq_table cpufreq_conservative cpufreq_powersave container video output dock sbs sbshc battery iptable_filter ip_tables x_tables ac parport_pc lp parport iTCO_wdt iTCO_vendor_support atl1c compat led_class serio_raw pcmcia_core evdev button shpchp pci_hotplug psmouse pcspkr ext3 jbd mbcache sg sr_mod cdrom sd_mod pata_acpi ata_generic ata_piix libata scsi_mod floppy ehci_hcd uhci_hcd usbcore thermal processor fan fuse vesafb fbcon tileblit font bitblit softcursor[  275.470975] Process test2 (pid: 5962, ti=f69a8000 task=f6818000 task.ti=f69a8000)
[  275.471022] Stack: 0000000a c018d562 00000000 f774ca80 c047d0e0 c0480500 c012ff48 f6818144 
[  275.471281]        c3032500 f760c500 c012ff48 f7c044d0 00000287 c012ff48 0000000a 00000010 
[  275.471543]        f6818000 f69537c0 f6818094 c013031c c01054c8 f69a9e80 f69a9e80 00000206 
[  275.471798] Call Trace:
[  275.471873]  [<c018d562>] __slab_free+0x202/0x2a0
[  275.471943]  [<c012ff48>] do_exit+0x188/0x850
[  275.472013]  [<c012ff48>] do_exit+0x188/0x850
[  275.472078]  [<c012ff48>] do_exit+0x188/0x850
[  275.472147]  [<c013031c>] do_exit+0x55c/0x850
[  275.472211]  [<c01054c8>] apic_timer_interrupt+0x28/0x30
[  275.472282]  [<c0105fd7>] die+0x277/0x280
[  275.472348]  [<c0106270>] do_invalid_op+0x0/0x90
[  275.472415]  [<c01062f1>] do_invalid_op+0x81/0x90
[  275.472482]  [<f8c67f8d>] vmx_vcpu_load+0x17d/0x1c0 [kvm_intel]
[  275.472561]  [<c0115fcd>] native_smp_call_function_mask+0x5d/0x180
[  275.472634]  [<c018cb46>] check_bytes_and_report+0x26/0xd0
[  275.472701]  [<c018c869>] slab_pad_check+0x69/0xe0
[  275.472772]  [<c031dfd2>] error_code+0x72/0x80
[  275.472840]  [<f8c67f8d>] vmx_vcpu_load+0x17d/0x1c0 [kvm_intel]
[  275.472910]  [<c018d562>] __slab_free+0x202/0x2a0
[  275.472977]  [<f8c8215b>] kvm_arch_vcpu_setup+0x4b/0x60 [kvm]
[  275.473055]  [<f8c8215b>] kvm_arch_vcpu_setup+0x4b/0x60 [kvm]
[  275.473132]  [<f8c82d6c>] kvm_arch_vcpu_load+0xc/0x20 [kvm]
[  275.473208]  [<f8c81ec8>] kvm_arch_vcpu_destroy+0x8/0x30 [kvm]
[  275.473283]  [<f8c80613>] kvm_vm_ioctl+0x103/0x1c0 [kvm]
[  275.473362]  [<c01becea>] anon_inode_getfd+0x10a/0x150
[  275.473431]  [<f8c7f4ec>] kvm_dev_ioctl+0x13c/0x180 [kvm]
[  275.473506]  [<f8c80510>] kvm_vm_ioctl+0x0/0x1c0 [kvm]
[  275.473584]  [<c019e5db>] do_ioctl+0x2b/0x90
[  275.473650]  [<c019e86e>] vfs_ioctl+0x22e/0x2b0
[  275.473715]  [<c019060e>] do_sys_open+0xbe/0xe0
[  275.473782]  [<c019e946>] sys_ioctl+0x56/0x70
[  275.473854]  [<c01043b2>] sysenter_past_esp+0x6b/0xa9
[  275.473924]  =======================
[  275.473964] Code: 83 50 30 00 89 b8 bc 03 00 00 8b 54 24 1c 83 02 01 8b 75 74 85 f6 74 1c 8d b6 00 00 00 00 8b 06 0f 18 00 90 8b 4e 08 89 f0 89 fa <ff> 51 04 8b 36 85 f6 75 ea 8b b7 a4 00 00 00 8b 9d a8 00 00 00 
[  275.475488] EIP: [<c031c18d>] schedule+0x13d/0x600 SS:ESP 0068:f69a9d34
[  275.475579] ---[ end trace c5cafd565f057c9f ]---
[  275.475621] Fixing recursive fault but reboot is needed!

Finally, the fourth and last patch, is the root CVE-2012-1601 fix, this
is the same backported patch Brad posted sometime ago, but
rediffed/fixed in this series. It really fixes the issue, without it the
following oops for example is possible:

[ 3495.948724] BUG: unable to handle kernel NULL pointer dereference at virtual address 0000007c
[ 3495.948801] printing eip: f8a9836c *pde = 00000000
[ 3495.948878] Oops: 0000 [#1] SMP
[ 3495.948950] Modules linked in: ipv6 af_packet rfcomm l2cap bluetooth ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 xt_state nf_conntrack ipt_REJECT xt_tcpudp bridge kvm_intel kvm ppdev acpi_cpufreq cpufreq_ondemand cpufreq_userspace cpufreq_stats freq_table cpufreq_conservative cpufreq_powersave container video output dock sbs sbshc battery iptable_filter ip_tables x_tables ac parport_pc lp parport atl1c compat led_class pcmcia_core serio_raw iTCO_wdt iTCO_vendor_support shpchp button evdev pci_hotplug pcspkr psmouse ext3 jbd mbcache sg sr_mod cdrom sd_mod pata_acpi ata_generic ehci_hcd floppy ata_piix libata scsi_mod uhci_hcd usbcore thermal processor fan fbcon tileblit font bitblit softcursor fuse
[ 3495.950622]
[ 3495.950655] Pid: 5992, comm: test Not tainted (2.6.24-32-generic #1)
[ 3495.950697] EIP: 0060:[<f8a9836c>] EFLAGS: 00010046 CPU: 3
[ 3495.950747] EIP is at kvm_apic_accept_pic_intr+0xc/0x50 [kvm]
[ 3495.950787] EAX: 00000000 EBX: 00000000 ECX: 00000000 EDX: 00000001
[ 3495.950829] ESI: f72fe000 EDI: f73aa000 EBP: 00000000 ESP: f73dfd68
[ 3495.950871]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
[ 3495.950911] Process test (pid: 5992, ti=f73de000 task=f70ea5c0 task.ti=f73de000)
[ 3495.950954] Stack: f72fe000 f8a9739d 00000000 f8a7049d 00000000 00000000 f72fe000 f73aa000
[ 3495.951173]        f8a8d8de c3029550 c3025b00 c3029534 c3029550 f73bbb40 f72fe000 0000ae80
[ 3495.951392]        f8a88c7d c01227eb c3025b00 c0328aa0 00000002 c0122847 f703c000 c01214c2
[ 3495.951610] Call Trace:
[ 3495.951677]  [<f8a9739d>] kvm_cpu_has_interrupt+0x1d/0x40 [kvm]
[ 3495.951747]  [<f8a7049d>] vmx_intr_assist+0x2d/0x1d0 [kvm_intel]
[ 3495.951812]  [<f8a8d8de>] kvm_arch_vcpu_ioctl_run+0xae/0x610 [kvm]
[ 3495.951883]  [<f8a88c7d>] kvm_vcpu_ioctl+0x34d/0x360 [kvm]
[ 3495.951948]  [<c01227eb>] enqueue_entity+0x2b/0x60
[ 3495.952011]  [<c0122847>] enqueue_task_fair+0x27/0x30
[ 3495.952070]  [<c01214c2>] enqueue_task+0x12/0x30
[ 3495.952128]  [<c0121535>] activate_task+0x25/0x40
[ 3495.952186]  [<c0125d0e>] try_to_wake_up+0x4e/0x350
[ 3495.952247]  [<c031f93f>] do_page_fault+0x13f/0x730
[ 3495.952308]  [<c0140d54>] autoremove_wake_function+0x14/0x40
[ 3495.952368]  [<c012196b>] __wake_up_common+0x4b/0x80
[ 3495.952428]  [<c012413e>] __wake_up+0x3e/0x60
[ 3495.952487]  [<c012cc2b>] wake_up_klogd+0x3b/0x40
[ 3495.952550]  [<c01a4414>] d_alloc+0x114/0x1a0
[ 3495.952607]  [<c01bd25f>] inotify_d_instantiate+0xf/0x40
[ 3495.952666]  [<c01900de>] fd_install+0x1e/0x50
[ 3495.952724]  [<c01becea>] anon_inode_getfd+0x10a/0x150
[ 3495.952785]  [<f8a88587>] kvm_vm_ioctl+0x77/0x1e0 [kvm]
[ 3495.952855]  [<c0262276>] tty_ldisc_deref+0x46/0x70
[ 3495.952914]  [<c026448b>] tty_write+0x1cb/0x1e0
[ 3495.952972]  [<f8a88930>] kvm_vcpu_ioctl+0x0/0x360 [kvm]
[ 3495.953040]  [<c019e5db>] do_ioctl+0x2b/0x90
[ 3495.953098]  [<c019e86e>] vfs_ioctl+0x22e/0x2b0
[ 3495.953157]  [<c019e946>] sys_ioctl+0x56/0x70
[ 3495.953215]  [<c01043b2>] sysenter_past_esp+0x6b/0xa9
[ 3495.953276]  [<c0310000>] unix_dgram_disconnected+0x20/0x70
[ 3495.953338]  =======================
[ 3495.953374] Code: 7c 31 d2 8b 88 80 00 00 00 89 c8 25 f0 00 00 00 0f ac d0 04 c1 ea 04 5b c3 8d b6 00 00 00 00 53 8b 98 78 01 00 00 31 c9 8b 40 10 <8b> 53 7c 85 c0 8b 92 50 03 00 00 75 2a 8b 43 74 8b 88 70 01 00
[ 3495.954634] EIP: [<f8a9836c>] kvm_apic_accept_pic_intr+0xc/0x50 [kvm] SS:ESP 0068:f73dfd68
[ 3495.954735] ---[ end trace b5f8e9f5f2dc3dbf ]---

-- 
[]'s
Herton




More information about the kernel-team mailing list