[Bug 295629] Linuxlator fails to run the linux x86_64 binary: Program headers not in the first page

From: <bugzilla-noreply_at_freebsd.org>
Date: Thu, 28 May 2026 05:02:28 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295629

--- Comment #3 from Yuri Victorovich <yuri@freebsd.org> ---
Here is the problem analysis:

 Root Cause

  The copilot binary has an extremely non-standard ELF layout where the program
header table is placed at file offset 45,904,260 bytes (~44 MB into the file):

   Start of program headers:  45904260 (bytes into file)  # e_phoff = 0x2BC7184

  FreeBSD's ELF loader in sys/kern/imgact_elf.c enforces this check:

   static bool
   __elfN(phdr_in_zero_page)(const Elf_Ehdr *hdr)
   {
       return (hdr->e_phoff <= PAGE_SIZE &&
           (u_int)hdr->e_phentsize * hdr->e_phnum <= PAGE_SIZE - hdr->e_phoff);
   }

  This requires:

   1. e_phoff ≤ PAGE_SIZE (4096) — FAILS: 45,904,260 >> 4,096
   2. All program headers fit in the remainder of the first page

  The kernel only maps the first page of an executable into imgp->image_header
and immediately dereferences program headers from that buffer
(imgp->image_header + hdr->e_phoff). If e_phoff
  points beyond page 0, the data isn't there.

  Linux's kernel is different: load_elf_binary() uses kernel_read() to read
program headers at whatever offset e_phoff specifies, so it handles this layout
fine.

  Why is the binary like this?

  The copilot binary (a Go binary) is built with debug info embedded, and has
an unusual segment layout — its first LOAD segment covers 0x3315b0 (~3.1 MB) of
read-only data placed before
  the executable code, with the program header table appended after most of the
file content rather than near the ELF header. In a normal ELF binary, e_phoff =
64 (immediately after the
  64-byte ELF header).

  Kernel fix: Extend FreeBSD's ELF loader to use vn_rdwr to read program
headers at arbitrary offsets (like Linux does), instead of requiring them in
the first page.

-- 
You are receiving this mail because:
You are the assignee for the bug.