Bug 505641 (CVE-2009-3616)
| Summary: | CVE-2009-3616 Remote VNC client can cause any QEMU VNC server to crash with a double-free | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 5 | Reporter: | Daniel Berrangé <berrange> | ||||||||||
| Component: | kvm | Assignee: | Eduardo Habkost <ehabkost> | ||||||||||
| Status: | CLOSED ERRATA | QA Contact: | Lawrence Lim <llim> | ||||||||||
| Severity: | medium | Docs Contact: | |||||||||||
| Priority: | low | ||||||||||||
| Version: | 5.4 | CC: | bressers, cpelland, ehabkost, green, lihuang, ovirt-maint, Rhev-m-bugs, security-response-team, sghosh, tburke, thoger, tools-bugs, vdanen, virt-maint, ykaul | ||||||||||
| Target Milestone: | rc | Keywords: | Security | ||||||||||
| Target Release: | --- | ||||||||||||
| Hardware: | All | ||||||||||||
| OS: | Linux | ||||||||||||
| Whiteboard: | |||||||||||||
| Fixed In Version: | kvm-83-82.el5 | Doc Type: | Bug Fix | ||||||||||
| Doc Text: | Story Points: | --- | |||||||||||
| Clone Of: | 505640 | Environment: | |||||||||||
| Last Closed: | 2009-09-02 09:33:36 UTC | Type: | --- | ||||||||||
| Regression: | --- | Mount Type: | --- | ||||||||||
| Documentation: | --- | CRM: | |||||||||||
| Verified Versions: | Category: | --- | |||||||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||||||
| Embargoed: | |||||||||||||
| Bug Depends On: | 505640, 537902, 537903 | ||||||||||||
| Bug Blocks: | |||||||||||||
| Attachments: |
|
||||||||||||
|
Description
Daniel Berrangé
2009-06-12 17:53:24 UTC
I've reproduced this crash on the RHELV/RHEL-5.4 trees too with kvm-83-59.el5ovirt Let's fix it in future releases. I don't see any security issue since if someone can access the host network it can only crash qemu the most. I believe there are 2 things to consider here: - This can be an issue in setups where user has VNC console access to the system where (s)he does not have admin privileges. I believe this VNC crash takes qemu process, hence effectively kills VM. Given that VNC access is console access, hence allowing things like reboot to single user mode, I presume such access is never granted to any untrusted user, and hence bug only gives sufficiently privileged user yet another way to shoot herself in the foot. - Is this limited to double-free? Possible exploitable memory corruptions in this case may need to be treated as possible guest -> host escape. Does the same affect EL5 Xen's qemu? Agree with point 1, that if a user has VNC console access they can be assumed to be the guest administrator. It was the point 2 that I'm not so sure of yet, so I'm doing a build of QEMU with VNC debugging enabled to figure out the precise sequence of errors. RHEL-5 Xen's QEMU is not impacted. It is a much older codebase without the audio capture code present at all. Ok, here's what's going on in QEMU's vnc.c file First to clarify my original steps to reproduce. When I said to reproduce > 5. Send the following 3 bytes to the server > > 255 > 1 > 0 You actually need to send one extra byte, where the 4th byte is > 2, eg this will do the trick 255 1 0 255 When the client message arrives in the server, it invokes: static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) This particular audio extension message gets handled by the last case statement , which expects a u8 followed by a u16. The bug involves sending an unhandled value for the u16 field [...snip...] case 255: if (len == 1) return 2; switch (read_u8(data, 1)) { case 0: if (len == 2) return 12; ext_key_event(vs, read_u16(data, 2), read_u32(data, 4), read_u32(data, 8)); break; case 1: if (len == 2) return 4; switch (read_u16 (data, 2)) { [...snip...] default: printf ("Invalid audio message %d\n", read_u8(data, 4)); vnc_client_error(vs); break; } break; default: printf("Msg: %d\n", read_u16(data, 0)); vnc_client_error(vs); break; } break; default: printf("Msg: %d\n", data[0]); vnc_client_error(vs); break; } vnc_read_when(vs, protocol_client_msg, 1); return 0; } So in this bug, we get the 'Invalid audio message' and then call 'vnc_client_error(vs)'. This function actually *frees* the 'vs' parameter. Now protocol_client_msg goes onto call vnc_read_when(vs,...), which scribbles on the just-freed memory. Control returns to vnc_client_read, which reads just-freed memory, and because we didn't reset vs->csock back to -1 after closing the socket, vnc_client_read does another loop iteration, calling back into protocol_client_msg. This causes the second error message on console 'Msg: 0', and then calls vnc_client_error again, resulting in the double free. You can probably exercise other codepaths in protocol_client_msg() with careful choice of data on the wire. So there are reads & writes to free'd memory, and then the subsequent double-free. This problem appears much much more widespread than just the audio extension. It appears Mark has separately identified countless other scenarios in which a client can crash the server https://bugzilla.redhat.com/show_bug.cgi?id=501131 this all stems from the recent change to split client & server state out into separate structs. Previously all this usage was safe because the 'vs' object would never be freed. Created attachment 348075 [details]
fix use after free.
Can you give it a spin?
Created attachment 348096 [details]
fix more use-after-free cases
Found a few more places where we have to take care while preparing a version for upstream.
Created attachment 348099 [details]
The two fixes combined into one patch.
Created attachment 348111 [details] Delibrarely broken VNC audio client to crash server To reproduce the problem, apply the attached patch, to this commit of gtk-vnc client, rebuild and run its demo client app ./examples/gvncviewer localhost:1 (assuming you have QEMU on localhost:1 too of course) http://git.gnome.org/cgit/gtk-vnc/commit/?id=6634acb2ccaf01e237fc03ed9f15b25e6f9897b6 Gives me just a "Invalid audio message 255" on stderr (with patch #9 applied). No qemu crash, guest continues to run. Try it again. It usually crashes first time for me, but occassionally needs to be run a couple of times, since it is a tiny bit susceptible to kernel schedular variations As we have a patch, I will propose this for rhel-5.4.0/rhev-2.1, in case it get positive results and reviews. FYI, a much easier way to demonstrate the crash is using the rdesktop program, eg rdesktop hostname:port It exercises the same basic problem, although not quite the same codepath as my original demo using the steps in comment #20. reproduce the bug in kvm-83-80.el5 ( host RHEL5u4 beta ) verified in kvm-83-83.el5 steps : 1. start guest by command : /usr/libexec/qemu-kvm -cdrom ~/boot.iso -vnc :15 2. run ` rdesktop host_ip:15 ` in another terminal. effect : 1 kvm-83-80.el5 : segfault. (gdb) bt #0 qemu_del_timer (ts=0x13f2dd0) at /usr/src/debug/kvm-83-maint-snapshot-20090205/qemu/vl.c:1191 #1 0x000000000049336a in vnc_client_io_error (vs=0x1502010, ret=<value optimized out>, last_errno=<value optimized out>) at vnc.c:804 #2 0x0000000000493a95 in protocol_version (vs=0x1502010, version=<value optimized out>, len=<value optimized out>) at vnc.c:2321 #3 0x000000000049657b in vnc_client_read (opaque=<value optimized out>) at vnc.c:912 #4 0x00000000004098f2 in main_loop_wait (timeout=<value optimized out>) at /usr/src/debug/kvm-83-maint-snapshot-20090205/qemu/vl.c:3910 #5 0x0000000000516eaa in kvm_main_loop () at /usr/src/debug/kvm-83-maint-snapshot-20090205/qemu/qemu-kvm.c:599 #6 0x000000000040e415 in main (argc=5, argv=0x7fff47ea1858, envp=<value optimized out>) at /usr/src/debug/kvm-83-maint-snapshot-20090205/qemu/vl.c:3967 3 kvm-83-83.el5 # rdesktop 10.66.70.3:5901 Autoselected keyboard map en-us ERROR: Connection closed qemu-kvm not crash. An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on therefore solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHEA-2009-1272.html This was corrected in upstream qemu 0.11.0, however qemu in Fedora 10 and 11 is still affected by this issue (0.9.1-12.fc10 and 0.10.6-9.fc11 respectively). So Fedora still requires the fix. |