Crate memfd_runner

Crate memfd_runner 

Source
Expand description

§memfd-runner

A minimal Linux library for executing in-memory ELF files using memfd_create and execve.

This library provides a simple interface to load and execute ELF binaries directly from memory without writing them to disk. It uses Linux’s memfd_create system call to create an anonymous file in memory, writes the ELF data to it, then executes it via the /proc/self/fd/ interface.

§Features

  • Minimal - <400 lines of code, 1 dependency (syscaller)
  • Two execution modes - fork child process or replace current process
  • no_std - works in embedded and kernel environments

§Platform Support

  • Linux only - requires memfd_create system call (Linux 3.17+)
  • x86_64 - tested on x86_64 architecture

§Usage

§Simple execution (fork mode)

use memfd_runner::run;

let elf_bytes = std::fs::read("/usr/bin/echo").unwrap();
let exit_code = run(&elf_bytes).unwrap();
println!("Process exited with code: {}", exit_code);

§Replace current process

use memfd_runner::{run_with_options, RunOptions};

let elf_bytes = std::fs::read("/usr/bin/uname").unwrap();
let options = RunOptions::new().with_replace(true);
run_with_options(&elf_bytes, options).unwrap(); // Does not return

§Passing arguments and environment variables

use memfd_runner::{run_with_options, RunOptions};

let elf_bytes = std::fs::read("/usr/bin/echo").unwrap();
let options = RunOptions::new()
    .with_args(&["Hello", "World!"])  // Just the arguments, not the program name
    .with_env(&["PATH=/usr/bin", "HOME=/tmp"]);
let exit_code = run_with_options(&elf_bytes, options).unwrap();
// Executes: /proc/self/fd/X "Hello" "World!"

§Custom argv[0] (program name)

use memfd_runner::{run_with_options, RunOptions};

let elf_bytes = std::fs::read("/usr/bin/echo").unwrap();
let options = RunOptions::new()
    .with_argv0("my-echo")  // Custom program name
    .with_args(&["Hello", "World!"]);
let exit_code = run_with_options(&elf_bytes, options).unwrap();
// The program sees argv[0] as "my-echo" instead of "/proc/self/fd/X"

§Error handling

use memfd_runner::{run, RunError};

let invalid_elf = b"not an elf file";
match run(invalid_elf) {
    Ok(exit_code) => println!("Success: {}", exit_code),
    Err(RunError::InvalidElfFormat) => println!("Invalid ELF format"),
    Err(RunError::FdCreationFailed(errno)) => println!("Failed to create memfd: {}", errno),
    Err(e) => println!("Other error: {:?}", e),
}

§Limitations

  • Linux-specific
  • Maximum 32 command line arguments (256 chars each)
  • Maximum 64 environment variables (256 chars each)
  • Very basic ELF validation only (magic bytes, minimum size)
  • No support for complex ELF features or dynamic linking validation

Structs§

RunOptions
Options which can be used to customize arguments, environment and how the ELF is executed.

Enums§

RunError
Error types returned by memfd-runner operations.

Statics§

EMPTY_STRING

Functions§

run
Executes an in-memory ELF binary by creating a child process.
run_with_options
Executes an in-memory ELF binary with configurable options.