┌───────────────────────┐
▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ │
│ █ █ █ █ █ █ │
│ █ █ █ █ █▀▀▀▀ │
│ █ █ █ █ ▄ │
│ ▄▄▄▄▄ │
│ █ █ │
│ █ █ │
│ █▄▄▄█ │
│ ▄ ▄ │
│ █ █ │
│ █ █ │
│ █▄▄▄█ │
│ ▄▄▄▄▄ │
A deep dive into how the Linux kernel loads │ █ │
executable files │ █ │
~ dominikr └───────────────────█ ──┘
Introduction
------------
It has long been known[1][2] that the ELF executable format, as implemented by
Linux, is quite flexible in what it will accept vs what is specified in the
standard[3]. This has been exploited by Brian Raiter to create ELF files of a
minimal size[1], or by netspooky to thwart forensic analysis[2].
To the best of our knowledge, there has never been a rigorous analysis on how
exactly executable file loading works in the Linux kernel. This paper seeks to
rectify that, in the hope that it will pave the way for future shenanigans (see
the follow-up paper (in this issue of tmp.0ut) "Creating polyglot ELF files for
fun and anti-forensics" for one such example)
A basic familiarity with C and assembler code, and the structure of an ELF file
is assumed.
Methodology
-----------
The main tool used for exploring the Linux kernel sources was the Elixir Cross
Referencer[4], as it allowed to easily look up definitions across source files
and kernel versions.
The longterm 6.18 kernel was chosen as the primary reference, as it will
hopefully be free from short-term changes.
It was not possible to exhaustively analyze all supported architectures and
subarchitectures, both due to time constraints and hardware availability. Thus,
the main focus will be on the x86 architecture, and its major subarchitectures
X86_64, X86_X32_ABI and X86_32 (or IA32_EMULATION, respectively, when the kernel
is 64bit) [names as used in Kconfig]
Subarchitectures?
-----------------
Some CPU architectures have several major variants. For x86, one such major
addition was 64-bit mode. CPUs running in 64-bit mode can still execute 32-bit
code, which means that the same kernel can run 32-bit Intel 80386 binaries, as
well as 64-bit AMD x86-64 binaries.
To further complicate things, a new executable format for 64-bit Intel systems,
called x32 or elf32_x86_64, was introduced. It uses 32-bit pointers (and thus
also the 32-bit ELF format), but executes in 64-bit mode.
Other architectures like RISC-V, MIPS/Loongson and LoongArch, also both support
32- and 64-bit software (and Loongson is a compatible extension to MIPS, while
LoongArch is a MIPS extension which is no longer guaranteed to be compatible
with the original MIPS architecture)
Some CPUs also are bi-endian, supporting running code in either big- or
little-endian mode. And there's also middle-endian, but let's not go there.
Please also note that not all architectures might support running those variants
*at the same time*. That's what I meant when I said I didn't have the time nor
the HW to figure this whole mess out.
While "subarchitecture" is not an official term used by the kernel developers,
it is used in this paper to describe all those potential architecture variants.
Open questions at the beginning of this research
------------------------------------------------
While "how does the kernel exactly load ELF files?" is a general open question
that inspired this research, the specific question that lead to this deep dive
into the kernel sources concerns the X86_X32_ABI.
As already discussed, the Linux ELF loader is quite flexible. A 32-bit ELF for
e_machine == EM_386 does not care if the class byte (EI_CLASS) is set to 32- or
64-bit, nor does it care if the endianness (EI_DATA) is set to big or little.
Similarly, a 64-bit ELF for e_machine == EM_X86_64 also does not care for those
two values. This makes sense, as the e_machine field provides enough information
to deduct the values in both cases (x86 is always little-endian, and 32/64bit
have two distinct e_machine values).
But then - how does the Kernel load x32 binaries? The e_machine value for x32
is EM_X86_64 like for 64-bit ELF files, but it actually uses 32-bit structures
in the header, as previously mentioned. Hypotheses, such as that the kernel is
actually looking at the class byte if e_machine == EM_X86_64, but the file fails
to parse correctly, were quickly disproven. This question can of course be
extended to other architectures with multiple subarchitectures.
This lead to another question: can we create an ELF binary which loads as an x32
file if X86_X32_ABI is activated, but as a different 64-bit ELF file if it is
deactivated?
What actually happens inside the kernel
---------------------------------------
The Linux kernel has supported different executable file types over the decades,
starting with the a.out format, and transitioning to the ELF format around 1995.
Other supported formats are shellscripts, binfmt_misc, and, on some platforms,
COFF files.
Describing the process of using a syscall from userland, to where the kernel
actually tries to load an executable, will be skipped, as it is not relevant
to this paper.
Thus, our journey of trying to load an executable file begins in fs/exec.c:
| binfmt entry point: https://elixir.bootlin.com/linux/v6.18/source/fs/exec.c#L1651
| * try to load_binary() with every registered binfmt
| * proceed executing if the current handler set `point_of_no_return`
| * next format if retval was ENOEXEC, bail out otherwise
Of note is that this function will just try the next executable format, unless
the current executable format handler returns a different status than ENOEXEC.
In other words, it will try all loaders until one signals back that it can load
the file. The kernel uses the `point_of_no_return` field for signaling that
(see exec.c:1674).
The order of file formats to try is neither well-documented, nor obvious from
looking at the kernel sources. It seems that the order is implicitly defined in
`fs/Makefile`. (https://elixir.bootlin.com/linux/v6.18/source/fs/Makefile#L36)
What follows is an analysis of which conditions each relevant binfmt handler
will either return with ENOEXEC, or proceed along, in the order that the kernel
processes them. Non-ELF handlers will only be touched on, since they are not the
main focus of this paper.
| load_misc_binary: https://elixir.bootlin.com/linux/v6.18/source/fs/binfmt_misc.c#L202
| * pretty much anything accepted, depending on runtime config
The binfmt_misc loader is the first on the list, and it basically allows a user
to define arbritary new formats at runtime. Thus it will always return with
ENOEXEC, unless a match was found.
| load_script: https://elixir.bootlin.com/linux/v6.18/source/fs/binfmt_script.c#L34
| * has to start with '!#'
| * skip trailing/leading spaces/tabs, nonempty part in the middle
The binfmt_script loader never interferes with loading of ELF files, as the
header requirements are mutually exclusive with the ELF format.
| load_elf_binary: https://elixir.bootlin.com/linux/v6.18/source/fs/binfmt_elf.c#L832
| * check if ELFMAG == "\177ELF" (857)
| * type ET_EXEC or ET_DYN (860)
| * elf_check_arch: (862)
| * e_machine == EM_X86_64
| * elf_check_fdpic: not supported on x86 (864)
| * can_mmap_file: does not depend on content (866)
| * load_elf_phdr: (869)
| * check e_phentsize == 0x38 (531)
| * e_phnum > 0 (537)
| * e_phnum*e_phentsize <= 65536 (537)
| * for each phdr:
| * if PT_INTERP:
| * 2 <= p_filesz <= PATH_MAX (4096) (890)
| * can allocate memory? Else ENOMEM (894)
| * PATH is null-terminated (904)
| * interp not found? ENOENT and bail (909)
| * PT_GNU_STACK: check X flag (942)
| * parse_elf_properties (exec or interp if available) (993)
| * only on ARM64
| * arch_check_elf (1003)
| * only ARM64, MIPS, LoongArch
| * begin_new_exec (1010)
| * Sets "point_of_no_return", we're finished (1020)
This is the meat of the ELF loading/verification on Linux. While this confirms
many things already informally known, it reveals the exact order and explicit
details of ELF loading. Of note here is also the fact that e_machine *must* be
EM_X86_64, even if the kernel supports 32-bit and x32 binaries.
| (compat)load_elf_binary: https://elixir.bootlin.com/linux/v6.18/source/fs/compat_binfmt_elf.c
| * Mostly just binfmt_elf, with minimal macros to load 32bit compat format
| * compat_elf_check_arch:
| * e_machine == EM_386 || EM_486 || EM_X86_64
| * load_elf_phdr:
| * check e_phentsize == 0x20
This provides another key piece in understanding how ELF loading works under
Linux. compat_binfmt_elf.c is just a very thin wrapper around binfmt_elf.c,
merely redefining some key macros, allowing loading of *both* 32-bit and x32
binaries. Key differences compared to the regular load_elf_binary are listed.
Discussion
----------
### Answering the open questions
After going through the kernel's internal steps, we can solve the mystery of how
x32 binaries actually get loaded.
The kernel first wants to load our x32 binary as a regular 64-bit binary in
binfmt_elf.c. While the e_machine == EM_X86_64 test succeeds, the check for
e_phentsize == 0x38 will most likely fail, as that field is at different offsets
in 32-bit and 64-bit ELF formats, and thus will likely contain garbage.
But, the kernel will just try the next binfmt handler, in this case the one from
compat_binfmt_elf.c. This will succeed, because EM_X86_64 is still allowed,
while the e_phentsize check now looks for the correct value of 0x20 (at the
correct header offset for 32-bit ELF files).
Regarding the second question - loading a binary as an x32 file only when
X86_X32_ABI is activated does not seem to be possible, as the kernel will always
first try to load it as a 64-bit binary, and only tries as x32 if that fails.
Using a path to an interpreter (PT_INTERP program header) also doesn't work as a
switch, as that will lead to a ENOENT error from the binfmt handler, and thus
will also stop further handlers from running.
### Missing endianness checks
Another interesting thing to point out: there's no test for endianness anywhere.
Endianness of the executable is just implicitly assumed to be same as for the
currently running system. In practice, this will lead to a fail at the type
check (ET_EXEC or ET_DYN), as this is the first multi-byte field, and thus the
first where endianness matters (ELFMAG == "\177ELF" is a byte-based test and
will thus work regardless of endianness).
### Kernel architecture
It seems that the kernel devs were careful about not introducing any decision
points that depend on external factors (e.g. if interpreter exists [ENOENT], or
trying to allocate large amounts of memory [ENOMEM]), instead failing the
execution with a fatal error. If memory allocation didn't fail with ENOMEM,
it could have been used to discern between CPUs who support 5-level paging and
those who don't (see the paper by lm978 for more information about 5-level
paging[6]). The only ways for non-fatally failing late during the execution of
binfmt_elf.c seems to be a wrong phentsize, or an illegal PT_INTERP header.
Using this newly-learned knowledge for good
-------------------------------------------
### A more robust way of identifying ELF files
We've determined how little the Linux kernel actually parses of the ELF file,
and how this complicates identifying if a binary is actually 32- or 64-bit,
and if it is big or little endian.
Can we use what we learned from how the kernel parses ELF file to create a more
robust way of getting this information?
First, we must figure out the endianness of a binary, as this will change how
every multibyte field in the ELF header is interpreted. As explained in the
discussion section, the kernel itself makes no attempt to check for the
endianness of an ELF file. But in the very next sentence, we conclude that a
kernel trying to load a wrong endian file will most likely fail at the type
check of the ELF file. This field is well-suited, as there are only a few
values of interest to us (ET_EXEC equals 2, and ET_DYN equals 3).
Fortunately, this field is also in the very beginning of the ELF header, at
position 0x10, where the field offsets for 32- and 64-bit ELF files do not
differ yet[9]. Thus we have found a suitable method for checking for
endianness.
How do we check for 32/64bit then? The e_machine field is not suitable, as
several subarchitectures can share the same e_machine value. But the e_phent
field is fit for that task, as it has two distinct values for 32- and 64-bit
ELF files. Or, better said, the e_phent *fields*, as they now are in two
different locations[9].
#### The final algorithm
| 1. Check beginning of file for string "\177ELF"
| 2. Read e_type from offset 0x10, as little endian value
| Assume little endian if value < 0xFE
| Assume big endian otherwise
| Warn if if not ET_EXEC or ET_DYN
| 3. Read e_phentsize32 from offset 0x2A
| Read e_phentsize64 from offset 0x36
| Assume 32-bit if e_phentsize32 == 0x20
| Assume 64-bit if e_phentsize64 == 0x38
| Warn about the file potentially being a polyglot ELF if both values
| match
| 4. Check that e_phnum > 0, and e_phnum*e_phentsize <= 65536
The same test as in the kernel was added for step 1, to see if the file is
*potentially* an ELF file. The endian test was extended to check if value <
0xFE, to correclty identify ELF files of type ET_LOOS, ET_HIOS, ET_LOPROC
and ET_HIPROC[9].
#### A proof-of-concept implementation, and its verification
A proof-of-concept of the algorithm was implemented as a shellscript with the
name `elfid`. This language was chosen because it should come preinstalled on
any system that supports ELF binaries.
The tool checks ELF files like the Linux kernel would, and prints diagnostics
if a file would not be loaded. It prints out information about the file in
a style similar to the `file` utility, and warns if it detects any
inconsistencies.
For testing and verification, the test corpora of both Radare2[10] and Rizin[11]
were used. Interestingly, no file in these corpora has any inconsistencies in
the 32/64bit or endianness flags.
Run on `tiny-x64` from Brian Raiters collection[12], the tool gives out this
information vs GNU file:
$ file tiny-x64
tiny-x64: ELF, unknown class 176
$ ./elfid tiny-x64
EI_CLASS has illegal value: 176, should be 2 (ELFCLASS64)
EI_DATA has illegal endian value: 41, should be 1 (little)
EI_VERSION has illegal version: 94, should be 1
tiny-x64: ELF 64-bit LSB pie executable, x86-64, version 94 (unknown ABI 64)
All e_machine types found in the corpora were added to the program, as well
as all encountered OSABI types. While there are bigger databases of e_machine
types (in e.g. the binutils readelf, or the elfutils readelf), those were not
included, as not a single actual ELF file could be found for many listed
architectures.
If the environment variable `FORCE` is set to a non-null variable, elfid will
continue if an error is encountered. This might be useful when trying to analyze
severely broken ELF files.
Using this newly-learned knowledge for evil
-------------------------------------------
### Exploiting the seldomly-used e_machine == EM_486
One surprising find was the support for the EM_486 (6) e_machine value. It is
an alias for the much more commonn EM_386 (3), but is poorly supported in many
tools. It's use in anti-forensics has been documented by the author in [5],
building upon an unpublished, earlier version of this paper.
### Exploiting PT_GNU_STACK parsing differences
The PT_GNU_STACK program header is used to mark the stack of an ELF executable
explicitly as either executable or non-executable. The kernel uses only the
least-significant bit of the flag field (PF_X) for that, while tools like
checksec used to look at all 3 permission bits at once.
So, you can trick checksec into thinking an ELF file has a nonexecutable stack,
by just setting the permission bits to " WE" instead of "RWE". This first bug
was fixed several years ago[7], but there's another bug hiding: the kernel loops
through all PHDRs, and updates the executable_stack flag each time a
PT_GNU_STACK header is encountered. The newest Go version of checksec is still
vulnerable as of today, because it returns on the *first* PT_GNU_STACK header
encountered[8].
Future work
-----------
As mentioned, there's already a second paper from the same author in this
issue of tmp.0ut.
The research of this paper could be extended to other architectures like ARM/
ARM64 and RISC-V.
Future areas of research could be the ELF loaders of other operating systems,
namely the *BSD family. Preliminary research has shown that it is e.g. possible
to create an ELF file that will run in FreeBSD's Linux emulation layer, but not
on an actual Linux system itself.
References
----------
[1] https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
[2] https://tmpout.sh/2/3.html
[3] https://refspecs.linuxbase.org/elf/elf.pdf
[4] https://elixir.bootlin.com/
[5] https://github.com/dominikfhnw/bggp6-writeup/tree/main/allinone#scoringbonus-points
[6] https://tmpout.sh/3/22.html
[7] https://github.com/slimm609/checksec/commit/532330e34947080e4c527ce5cb6f1fc4f773f82a
[8] https://github.com/slimm609/checksec/blob/main/pkg/checksec/nx.go#L55
[9] https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#ELF_header
[10] https://github.com/radareorg/radare2-testbins
[11] https://github.com/rizinorg/rizin-testbins
[12] https://www.muppetlabs.com/~breadbox/software/tiny/return42.html
Appendix A - elfid tool
-----------------------
base64 -d<<'E-O'|zcat>"elfid"&&echo OK
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
E-O
--[
PREV |
HOME |
NEXT ]--