A decades-old mystery within the Linux kernel is finally being laid to rest! For nearly 30 years, an obscure kernel limitation has silently plagued specific ELF files on Linux AArch64 systems, causing frustrating “exec format errors.” This deep dive uncovers the surprising history of a hidden check dating back to Linux v0.99 and explains how a diligent engineer, supported by historical sleuthing, paved the way for its removal in the upcoming Linux 6.17. Discover how this crucial update will enhance the robustness and compatibility of your Linux system.
Unearthing a Decades-Old Linux Kernel Mystery
A Problematic ELF File on Linux ARM64
An engineer at Alibaba recently reported a peculiar issue: a script-generated Assembly file, successfully compiled by GCC into an ELF file, would mysteriously fail to run on Linux AArch64 (ARM64) systems configured with the standard 4K page size kernel. The error, an uninformative “exec format error,” baffled debugging efforts. Curiously, the very same ELF file executed without a hitch if the ARM64 system was using the more modern 64K page size.
Further investigation revealed the root cause: a specific check within one of the kernel’s ELF loading functions. This check would cause the system to bail out if the ELF file’s size, specifically related to its program headers, exceeded a certain threshold determined by ELF_MIN_ALIGN / PAGE_SIZE
. In this particular case, the ELF file contained 78 program headers, which surpassed the imposed limit of 74 headers for a 4K page size. For a 64K page size, the limit was significantly relaxed to over 1,184 program headers, explaining why the file ran successfully there.
The Technical Deep Dive: Understanding the ELF Program Header Hurdle
Kees Cook’s Deep Dive into Linux History
The arbitrary nature of this limitation prompted a historical inquiry. Longtime Linux kernel developer Kees Cook embarked on a journey through the “pre-Git” source code archives – a challenging task given the lack of linked history in those early versions. His meticulous search uncovered that this elusive check appeared with the “Import 0.99.15f” tag, specifically when ELF interpreter support was initially added around September 1993. Intriguingly, no rationale or explanation for its inclusion was ever documented. It was later extended to non-interpreter loads as well.
As Cook noted, the original intent might have been to prevent large memory allocations from userspace, but modern Linux systems, with advancements like IPC and BPF, routinely handle far larger allocations, making the original `PAGE_SIZE` check largely redundant and, in this case, problematic.
Lifting the Long-Standing Linux 6.17 Kernel Limitation
Impact and Future Outlook for Linux Systems
Thanks to this thorough investigation, a patch has now been submitted for the upcoming Linux 6.17 merge window. This critical patch aims to remove the antiquated `ELF_MIN_ALIGN` limitation on program headers, bringing the Linux kernel‘s behavior in line with the official ELF specification, which imposes no such restriction. While a 64K size limitation will still technically exist, it is sufficiently high to not be a practical concern for typical ELF files.
Assuming no objections are raised by Linus Torvalds himself, this fix is expected to be merged, likely as soon as the Linux 6.17 merge window opens following the release of Linux 6.16. This update promises to enhance the robustness of Linux AArch64 systems, ensuring a wider range of legitimate ELF binaries can execute without encountering obscure, decades-old “exec format errors.” It’s a testament to the ongoing refinement and commitment to compatibility within the Linux development community.
FAQ
Question 1: What is an ELF file and why is it important for Linux?
An ELF (Executable and Linkable Format) file is a standard file format for executables, object code, shared libraries, and core dumps in Unix-like operating systems, including Linux. It’s crucial because it defines how the operating system loads and runs programs, making it fundamental to how software interacts with the Linux kernel.
Question 2: What is “page size” in the context of the Linux kernel and why does it matter?
Page size refers to the fixed-size blocks of memory that the Linux kernel manages. Common sizes are 4KB and 64KB (especially on ARM64). It matters because memory is allocated and managed in these units. Differences in page size can affect memory efficiency, performance, and, as seen in this article, how certain ELF files or kernel checks behave.
Unique Tip: You can check your Linux system’s default page size using the command getconf PAGE_SIZE
or cat /proc/meminfo | grep 'PageTables'
(though `getconf` is more direct for the base page size).
Question 3: What’s the significance of this fix for Linux AArch64 users?
For Linux AArch64 users, especially those running systems with a 4K page size, this fix is significant as it resolves a long-standing “exec format error” that could prevent legitimate, GCC-compiled ELF files with many program headers from executing. It enhances system compatibility and robustness, ensuring that the kernel adheres more closely to the open ELF specification rather than an arbitrary, undocumented historical limitation.