Assuming no objections are raised by Linus Torvalds, an early pull request has been submitted for the upcoming Linux 6.17 merge window to address an obscure kernel limitation that has been in place going back all the way to 1993 during the Linux v0.99 kernel days.
A Linux engineer working at Alibaba recently reported on a script-generated Assembly file that when built by the GCC compiler and running as an ELF file it would fail to run on Linux AArch64/ARM64 if using the standard 4K page size. But if using the modern 64K page size for ARM64 this ELF file would work just fine. An “exec format error” would happen when using a 4K page kernel size on ARM64 with this particular binary.
The Alibaba engineer noted that within one of the load ELF functions in the kernel was a check to see if the size was greater than ELF_MIN_ALIGN / PAGE_SIZE and bail out if that is the case, which it was given the number of program headers in this particular ELF file. But it wasn’t clear why this check was in place and if removing the check it could work fine on a 4K kernel.
Longtime Linux developer Kees Cook dug through the old pre-Git code to try to figure it out. He explained:
“Looking through https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git (which doesn’t have linked history, so you have to examine explicit “pre git” tags), I see:
4779b38bcb96 (“[PATCH] Linux-0.99.13 (September 19, 1993)”) Which says “ELF binary support it a notable change.” Here, the PAGE_SIZE
check does not exist. When ELF interp support was added in 9e11983a5a3e (“Import 0.99.15f”), we see the check appear, and I can
find no rationale.And with 6a8d38945cf4 (“binfmt_elf: Hoist ELF program header loading to a function”), the PAGE_SIZE check is _added_ for non-interp loads.
It seems the 64K count limit is sufficient? (If the goal was to avoid large memory allocations happening from userspace, we’re way past PAGE_SIZE these days between IPC, BPF, etc.) Does this work for you?”
So now for Linux 6.17 is a patch to drop the 4K limitation of the program header size.
“We have assembly code generated by a script. GCC successfully compiles it. However, the kernel cannot load it on an ARM64 platform with a 4K page size. In contrast, the same ELF file loads correctly on the same platform with a 64K page size.
The root cause is the Linux kernel’s ELF_MIN_ALIGN limitation on the program headers of ELF files. The ELF file contains 78 program headers (the script inserts many holes when generating the assembly code). On ARM64 with a 4K page size, the ELF_MIN_ALLIGN enforces a maximum of 74 program headers, causing the ELF file to fail. However, with a 64K page size, the ELF_MIN_ALIGN is relaxed to over 1,184 program headers, allowing the file to run correctly.
Cook kindly identified that this limitation was introduced in Linux-0.99.15f without an explanation for its purpose.
The ELF specification does not impose such a restriction on program headers. Removing the ELF_MIN_ALIGN limitation on program headers to align with the ELF spec. After removing ELF_MIN_ALIGN limitation, 64K size limitation still exist which should be sufficient.”
That patch was sent in as part of the execve changes for Linux 6.17. Assuming no issues discovered from Linus Torvalds himself, this fix should be merged once the Linux 6.17 merge window opens… Which will be as soon as Monday assuming Linux 6.16 goes as planned on Sunday.