Commit Graph

3 Commits

Author SHA1 Message Date
ceamac 1c186b0365 Fix -e/--exec namespace resolution on kernels without CONFIG_CHECKPOINT_RESTORE
/proc/<pid>/task/<pid>/children doesn't exist on every kernel (confirmed
missing on a real Android target), so resolve_namespace_pid() fell back to
the outer bwrap pid itself and nsenter ended up with no namespace flags at
all. Add a portable fallback that scans /proc/<n>/stat for the child whose
ppid matches, the same information pstree uses to build its tree.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gv3s5jckJKzh6JkMoi2Akz
2026-08-29 07:42:02 +00:00
ceamac 61f542080d Rename k-prefixed constants to snake_case, grouped in namespaces
Drop the k Hungarian-notation prefix throughout src/. Enum class values
(Mode::, OciPortProtocol::) are already qualified by the enum's own name,
so plain snake_case enumerators are enough. Free-standing constants also
move to snake_case; related ones are grouped under a named namespace
instead of relying on a shared prefix (main.cpp's getopt long-option
codes -> namespace options, bwrap.cpp's priv-drop path/binary name ->
namespace priv_drop). kMountProgram, which was actually mutable global
state rather than a true constant, is renamed to g_mount_program to
match this codebase's existing g_ convention for that kind of state.
Also dedupes the three identical kTabWidth local constants in main.cpp
into one shared tab_width.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gv3s5jckJKzh6JkMoi2Akz
2026-08-24 12:59:26 +00:00
ceamac 00482b6b42 Add -e/--exec to join a running -r/--run session
Validates the given pid against the same tracked-session liveness
check --list-processes/--clean-processes already use, then joins its
namespaces via nsenter and runs a command there in the foreground.

Two things discovered only by testing against a live session, not
assumed up front:

- The tracked pid is bwrap's own outer process. It sets up the
  mount/user namespaces itself, then clone()s the actual sandboxed
  command into fresh pid/uts/ipc/cgroup namespaces -- clone()'s
  namespace flags only ever affect the new child, never the caller,
  so the outer process itself never enters those namespaces at all.
  exec_in_session() resolves that real child via
  /proc/<pid>/task/<pid>/children and joins its namespaces instead,
  falling back to the outer pid if that can't be read.

- Rather than nsenter -a (which would hit a known "Invalid argument"
  failure re-entering an identical namespace -- this project already
  worked around exactly that once, for the containers-storage mount
  path), each namespace type is only joined if
  /proc/<pid>/ns/<type> actually differs from this process's own.
  nsenter also needs --preserve-credentials, or it tries to
  setuid/setgid/setgroups to the target's identity, which fails
  outright against the setgroups-denied unprivileged user namespace
  bwrap creates whenever -r/--run isn't root.

Verified end-to-end: joined shell gets the container's own hostname,
process tree (ps shows only container processes), and root
filesystem; untracked/stale pids error out cleanly without touching
nsenter; Ctrl-C during the joined command doesn't disturb the
original session; no leftover mounts after either exits.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gv3s5jckJKzh6JkMoi2Akz
2026-08-22 09:41:32 +00:00