Skip to content

Guest execution architecture: reaching "any Linux tool works" beyond proot's ptrace ceiling #117

Description

@mega123-art

Summary

Every guest-execution bug we've hit (#112 git corruption, #115 link false-success, bun install failure, the failed glibc-native T0) traces to one architectural root: proot uses ptrace, a lossy syscall-translation layer forced on us by unrooted Android (untrusted_app blocks namespaces/root). We've fixed the widespread cases with targeted patches, but ptrace has a ceiling some tools sit above. This issue frames the long-term "any Linux tool works" architecture decision so it's made deliberately, not one band-aid at a time.

What's already fixed (proot patches, shipped/in-flight)

What proot CANNOT fix (the ceiling)

  • bun — its installer opens node_modules as a directory fd then forks ~14 workers doing openat(dirfd, …)/linkat relative to that fd. proot can't correctly track dirfd→path across parallel ptraced processes → workers get ENOENT on an existing dir → Failed to install N packages, empty node_modules, misleading exit 0. Not the Run the engine natively (no proot in the hot path): structural fix for the untrusted_app transport corruption #115 bug (copyfile backend fails identically); not config-fixable. Parallel + fd-relative ops are exactly where ptrace sandboxes break down. (Even native Termux struggles to run bun.)
  • glibc-native (T0, #115 comment) — running our glibc rootfs binaries directly under Android's bionic linker is impossible (ET_EXEC rejected; glibc rtld aborts; PIE glibc still segfaults). So "just drop proot for the current rootfs" is off the table.
  • General ceiling: io_uring, complex fd-relative flows, some namespaces — anything ptrace can't faithfully mediate.

Reference: what Termux does

Termux's native environment is not proot — its ~2000 packages are compiled against bionic and run as real app processes (no ptrace) → real syscalls, hardlinks, fd semantics all work. When Termux needs glibc (real Ubuntu) it uses proot-distro — the same proot, the same bugs we have. So Termux "wins" only by avoiding proot for its own tools, at the cost of a fully bionic userland. Their Play-Store build execs those bionic PIE binaries via /system/bin/linker64 (our T0 confirmed that path works for bionic PIE, not for glibc).

The decision: how do we reach "any Linux tool works"?

Option What Fixes bun / exotic tools? Cost / risk
A. Stay on proot, patch per-tool keep glibc rootfs; fix tools as they break (l2s, git/pnpm config, …) No — ceiling stays Low per fix, but unbounded tail; can't cover parallel/fd-relative/io_uring tools
B. Native bionic userland (Termux model) rebuild engine (node/git/…) as bionic PIE, run native via linker64, no proot in hot path; proot only for optional glibc Most tools yes; bun still uncertain (flaky even on native Termux) High — adopt/маintain a bionic userland, drop glibc rootfs; claude/codex ride native node (npm pkgs, OK once node runs)
C. microVM (Android AVF / pKVM) real Linux kernel in a VM; everything runs natively incl. glibc Yes — everything (real kernel: hardlinks, io_uring, fd, all) High + device-gated (needs AVF/pKVM: Android 13+, specific SoCs; MediaTek/Exynos support varies), perf/battery/size cost; fall back to proot where AVF absent

Recommendation

  • Short term: ship fix(android): #115 root cause — drop proot --link2symlink (fixes git, pnpm, all link() tools) #116 (fixes the real, common problem) and treat bun as unsupported-under-proot (document it; agents use npm which works). Don't rebuild the world for bun.
  • Long term: pick B or C deliberately if "arbitrary Linux tooling must work" is a real product requirement. C (AVF microVM) is the only path that fixes everything including glibc + exotic tools, but it's device-gated and needs a proot fallback. B (native bionic) removes ptrace for the engine but keeps a long tail (and doesn't clearly win bun).

Asks

  1. Decide whether "any arbitrary Linux tool works on-device" is a hard requirement or best-effort.
  2. If hard requirement → spike AVF availability across the target device matrix (Seeker/MediaTek, Snapdragon, Exynos) — that gates option C.
  3. Otherwise → adopt "proot + targeted fixes, bun/exotic unsupported" as the documented stance.

Related: #112, #114, #115 (+ PR #116). Evidence (probe harness, on-device traces) in debug/issue-115/ and the #115 comments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions