Crates.io | memfd-runner |
lib.rs | memfd-runner |
version | 0.2.2 |
created_at | 2025-07-30 20:43:11.518144+00 |
updated_at | 2025-08-02 14:15:25.508744+00 |
description | A Linux library for executing in-memory ELF files using memfd_create and execve |
homepage | https://github.com/mathyslv/memfd-runner |
repository | https://github.com/mathyslv/memfd-runner |
max_upload_size | |
id | 1774057 |
size | 60,320 |
A minimal Linux library for executing in-memory ELF files using memfd_create
and execve
.
memfd-runner 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.
no_std
- works in embedded and kernel environmentsmemfd_create
system call (Linux 3.17+)cargo add memfd-runner
Or add this to your Cargo.toml
:
[dependencies]
memfd-runner = "0.1.1"
use memfd_runner::run;
// Read an ELF binary
let elf_bytes = std::fs::read("/usr/bin/echo").unwrap();
// Execute it and get the exit code
let exit_code = run(&elf_bytes).unwrap();
println!("Process exited with code: {}", exit_code);
use memfd_runner::{run_with_options, RunOptions};
let elf_bytes = std::fs::read("/usr/bin/uname").unwrap();
let options = RunOptions::new().with_replace(true);
// This will replace the current process - does not return on success
run_with_options(&elf_bytes, options).unwrap();
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
let exit_code = run_with_options(&elf_bytes, options).unwrap();
// Executes: /proc/self/fd/X "Hello" "World!"
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"
use memfd_runner::{run_with_options, RunOptions};
let elf_bytes = std::fs::read("/usr/bin/env").unwrap();
let options = RunOptions::new()
.with_env(&["PATH=/usr/bin", "HOME=/tmp"]);
let exit_code = run_with_options(&elf_bytes, options).unwrap();
use memfd_runner::{run, RunError};
let invalid_data = b"not an elf file";
match run(invalid_data) {
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(RunError::TooManyArgs) => println!("Too many arguments provided"),
Err(e) => println!("Other error: {:?}", e),
}
run<B: AsRef<[u8]>>(bytes: B) -> Result<i32, RunError>
run_with_options<B: AsRef<[u8]>>(bytes: B, options: RunOptions) -> Result<i32, RunError>
RunOptions
- Configuration for execution
new()
- Create default options (fork mode)with_replace(bool)
- Set replace mode (true = replace process, false = fork child)with_args(&[&str])
- Set command line arguments (max 32 args, 256 chars each)with_env(&[&str])
- Set environment variables (max 64 vars, 256 chars each)with_argv0(&str)
- Set custom program name (argv[0])RunError
- Error types with context
FdCreationFailed(i32)
- Failed to create memory file descriptorBytesNotWritten(usize, usize)
- Write operation failed (written, expected)ExecError(i32)
- execve system call failedForkError(i32)
- fork system call failedWaitError(i32)
- wait4 system call failedInvalidElfFormat
- ELF validation failedTooManyArgs
- Too many command line arguments (limit: 32)TooManyEnvVars
- Too many environment variables (limit: 64)ArgTooLong
- Command line argument too long (limit: 256 chars)EnvVarTooLong
- Environment variable too long (limit: 256 chars)memfd_create()
to create an anonymous file in memoryexecve()
with /proc/self/fd/<fd>
path to execute the in-memory filememfd_create
system call (Linux 3.17+)cargo build
cargo test
cargo check
cargo clippy
cargo test
and cargo clippy
This project is dual-licensed under the MIT OR Apache-2.0 license. See LICENSE-MIT and LICENSE-APACHE files for details.