Skip to content

Fix exec module loading via 3i: marshal loader buffers through cage memory - #1364

Closed
rishabhBudhouliya wants to merge 2 commits into
enarx-7-13from
fix/exec-3i-cage-memory-marshaling
Closed

Fix exec module loading via 3i: marshal loader buffers through cage memory#1364
rishabhBudhouliya wants to merge 2 commits into
enarx-7-13from
fix/exec-3i-cage-memory-marshaling

Conversation

@rishabhBudhouliya

@rishabhBudhouliya rishabhBudhouliya commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Ports PR #1285 (exec loads its target through 3i instead of host file APIs) onto enarx-7-13 and fixes the bug that made it fail under grates.

The problem: the exec loader passed pointers to runtime heap buffers (the path string and the read buffer) into make_syscall. 3i validates every pointer against the calling cage's vmmap, so these pointers failed validation. Under the IMFS grate, every exec path silently resolved to the root directory and read returned EBADF.

The fix: exec now mmaps a small scratch region inside the exec-ing cage's own linear memory (same pattern as early_init_stack), writes the path there, reads the module in chunks through it, and unmaps it when done (also on error paths, via a Drop guard). Pointer args are passed in the same pre-translated form the wasmtime trampoline uses for guest syscalls.

Why this design:

  • No new trust is added. A "runtime pointer" flag would be forgeable by a guest, since syscall args are plain u64s, and would let the copy layer dereference arbitrary host memory. Marshaling through cage memory needs no such flag.
  • Grates keep full mediation. Runtime module loads look exactly like guest syscalls, so a grate that serves or denies open/read also serves or denies exec.

Related issues

Part of #1001. Applies the approach of #1285 on the enarx branch.

Testing

On lind server 3 under real SGX with the IMFS grate. All three cases failed instantly with EBADF before this change:

  • hello: execs from IMFS via 3i, exits 0
  • tcc: compiles hello.c, dumped object verified as valid ELF
  • gcc: driver execs via 3i and forks; cc1 (248 MB) reads through the grate but slowly (about 4 s/MiB), full pipeline verdict still pending

Compatibility and security impact

  • Exec targets can now live only in a grate filesystem (IMFS). Direct exec without a grate keeps working.
  • A grate that stubs open/read now also blocks exec of its children. This is intended: the grate mediates all child filesystem access.
  • The file still contains [instrument] eprintln debug lines from this investigation. They should be stripped before any of this moves toward main.

Checklist

  • I have read the contribution guidelines.
  • I added or updated tests where appropriate.
  • I ran the relevant tests locally and they pass.
  • I formatted the code and ran the relevant linters.
  • I updated documentation for user-visible or architectural changes.
  • I disclosed security vulnerabilities privately rather than in this PR.

@rishabhBudhouliya rishabhBudhouliya changed the title Fix exec module loading via 3i: marshal loader buffers through cage m… Fix exec module loading via 3i: marshal loader buffers through cage memory Aug 30, 2026
@Yaxuan-w Yaxuan-w closed this Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants