solo5: Solo5 executables should not be executable by a host kernel

If a user attempts to run a Solo5 executable directly (regardless of target), the host kernel will in most cases attempt to load and run the executable.

This is undesirable for several reasons:

  1. Bad UX for a “naive or beginning user”: Running such an executable directly produces Segmentation fault on Linux and Bus error (core dumped) on FreeBSD.
  2. Accidentally attempting to directly run a unikernel from an untrusted source is a potential security risk, since the host kernel’s ELF loader runs in kernel space.

I considered several solutions:

  1. Follow the ELF spec: set e_ident[EI_OSABI] to ELFOSABI_STANDALONE. Unfortunately the Linux (but not FreeBSD) ELF loader ignores these values entirely and will attempt to execute any ELF file with a matching processor architecture. Even if that were not the case, without providing our own Solo5-specific compiler toolchain we have no easy way to control these values in the resulting binary.

  2. Provide a “stub”: similarly to how PE executables have a DOS stub, that would be executed by the host kernel instead of the Solo5 start-up code. This is very hard, if at all possible, since tenders would have no way of distinguishing the “stub” PT_LOAD segment from the “real” PT_LOAD segments that doesn’t involve inventing out-of-spec schemes to distinguish the two.

  3. Provide a PT_INTERP pointing to a non-existent path: on Linux, this produces No such file or directory when attempting to directly run such a binary. On FreeBSD, this produces ELF interpreter /nonexistent/solo5 not found, error 2.

I’m going to go with option (3) as this is the least complex and best option overall. While the Linux response of No such file or directory is not ideal, it’s still better than the current Segmentation fault.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (14 by maintainers)

Commits related to this issue

Most upvoted comments

@cfcs:

Ah sorry, I misunderstood. You wrote:

With the current PR, if /nonexistent/solo5 is a directory then this can have unintended side-effects.

… but meant to say “With the current PR, if /nonexistent/solo5 is a file …”

In the extremely unlikely case that /nonexistent/solo5 is a file and a valid ELF executable, then yes, the kernel would attempt to load that as the interpreter and that is an unwanted side effect.

I’ll add / as you suggested. For reference, here’s what Linux and FreeBSD do in the various cases when using ‘/nonexistent/solo5/’ for PT_INTERP:

# Linux
$ tests/test_hello/test_hello.hvt 
bash: tests/test_hello/test_hello.hvt: No such file or directory
$ sudo mkdir -p /nonexistent/solo5
$ tests/test_hello/test_hello.hvt 
bash: tests/test_hello/test_hello.hvt: Permission denied
$ sudo rmdir /nonexistent/solo5/; sudo cp ./hello-static /nonexistent/solo5
$ tests/test_hello/test_hello.hvt 
bash: tests/test_hello/test_hello.hvt: Not a directory
# FreeBSD 12
$ tests/test_hello/test_hello.hvt
ELF interpreter /nonexistent/solo5/ not found, error 2
Abort trap
$ sudo mkdir -p /nonexistent/solo5
$ tests/test_hello/test_hello.hvt
ELF interpreter /nonexistent/solo5/ not found, error 13
Abort trap
$ sudo rmdir /nonexistent/solo5; sudo cp ./hello-static /nonexistent/solo5
$ tests/test_hello/test_hello.hvt 
ELF interpreter /nonexistent/solo5/ not found, error 20
Abort trap