In early 2023, security researchers discovered CVE-2022-48828, a subtle but impactful vulnerability in the Linux kernel’s Network File System daemon (NFSD). This article explains what the vulnerability was, why it happened, how it was fixed, and how attackers might abuse it. We'll provide code snippets and links for anyone wanting a deeper understanding.
What Is CVE-2022-48828?
CVE-2022-48828 is a Linux kernel vulnerability involving an "underflow" bug within the kernel’s NFS server component (NFSD). This bug occurs when an NFS client (remote or local) provides a file size value so large that it exceeds what the Linux kernel is able to handle, causing an integer wrap-around that can result in unexpected behavior—potentially leading to access issues or even data corruption.
Linux Kernel Versions: Prior to the patch (see references for details)
- Vulnerable code: Handling of file size (ia_size) during attribute decoding, especially via NFSv3 and NFSv4
Cause: Signed vs Unsigned Integer Handling
The core of the issue is a classic software mistake: mixing signed and unsigned numbers when their ranges don’t match up.
- NFSv3/NFSv4 Protocol: Defines file size as an _unsigned_ 64-bit integer (uint64_t), which allows for file sizes –18,446,744,073,709,551,615.
- Linux Kernel (ia_size): Uses a _signed_ 64-bit integer (loff_t/int64_t), with a range of –9,223,372,036,854,775,808 to +9,223,372,036,854,775,807.
This means an NFS client can specify a file size _larger_ than the kernel can keep in a signed type, causing the value to “wrap around” (underflow) and become negative in the kernel, which is not expected.
The Vulnerable Code
In the Linux kernel source <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/nfsd/nfs4xdr.c>, the attribute decoding logic translates the wire-protocol u64 file size into a signed loff_t field:
// decode_fattr4() inside fs/nfsd/nfs4xdr.c
if (fattr->valid & FATTR4_WORD4_SIZE) {
inode->i_size = fattr->size;
}
The underlying assignment doesn't check if fattr->size actually fits in a signed integer. If the NFS client sends a value above S64_MAX (9,223,372,036,854,775,807), the value will underflow and become negative.
An attacker-controlled NFS client could do this
import struct
import socket
# Send a SETATTR request with a file size of xFFFFFFFFFFFFFFFF (max u64)
file_size = xFFFFFFFFFFFFFFFF
payload = struct.pack(">Q", file_size) # NFS expects big-endian
# ... construct and send SETATTR operation with this payload ...
# The Linux server will read this into a signed variable!
Once decoded by the kernel, inode->i_size suddenly gets a massive negative number.
While no direct remote code execution is reported, this underflow opens the door for
- Denial of Service (DoS): Trying to allocate/write a file with a negative or impossibly large size may crash the kernel (BUG), Oops, or freeze a file system.
Data Corruption: Files could be truncated, grow unexpectedly, or gain bogus permissions.
- Local Privilege Escalation: Crafted exploit chains might work if attackers can predict/process negative sizes in filesystem operations such as mmap, read, or write.
The actual impact depends on how downstream code uses ia_size after the underflow.
How Was It Fixed?
The fix was simple but effective: all assignments that set ia_size now check if the value fits within the signed 64-bit limit, and bail out (error/return) if not.
Here’s the patch (see commit 822d670e848):
if (newsize > (u64)LLONG_MAX)
return nfserr_fbig;
iap->ia_size = newsize;
Translation
- If a new file size (newsize) is more than 9,223,372,036,854,775,807 (LLONG_MAX), bail with nfserr_fbig (File too big).
Otherwise, assign as normal.
Now, oversize values from the network are rejected, completely closing the door on this underflow.
Linux Kernel Patch:
NFSD: fix ia_size underflow (commit 822d670)
Kernel Bug Discussion:
NFS Protocol Definitions:
NFSv4 RFC 753 Sec 11.1 (file size is unsigned)
CVE entry:
Summary
CVE-2022-48828 is an example of a “hidden in plain sight” bug. It’s easy to overlook number-size mismatches, but they can have real and dangerous bugs in kernel-space code. If you run a Linux machine that uses NFSD/NFS server, make sure your kernel has this patch or later.
Key Takeaway:
When dealing with data from untrusted sources (especially over the network), always sanity-check the possible range and type. A single unchecked assignment can open up your kernel to unexpected behavior and attack.
Timeline
Published on: 07/16/2024 12:15:06 UTC
Last modified on: 05/04/2025 08:24:11 UTC