Skip to content

scope: gate analysis emission to the firmware process subtree#84

Merged
lacraig2 merged 1 commit into
mainfrom
scope-analysis-loggers
Jun 25, 2026
Merged

scope: gate analysis emission to the firmware process subtree#84
lacraig2 merged 1 commit into
mainfrom
scope-analysis-loggers

Conversation

@lacraig2

Copy link
Copy Markdown
Contributor

Problem

Penguin's per-process analysis loggers capture every process from boot — including Penguin's own infrastructure: the boot/init machinery, and the backgrounded vpnguin/console/guesthopper helpers that run for the entire guest lifetime. We want analysis scoped to the firmware-under-analysis's own process subtree.

The boundary is not temporal (a readiness gate can't exclude vpnguin, which runs the whole time) — it's process attribution.

Mechanism: inherited UTS-namespace marker, anchored on the initial namespace

penguin/src/resources/init.sh runs the real guest init in a fresh UTS namespace at handoff (unshare -u). The firmware subtree inherits that namespace across fork/exec, so it lives outside the kernel's initial namespace, while all Penguin infrastructure stays in it — including anything spawned via call_usermodehelper, which lands in the initial namespace.

igloo_in_scope(task) = task->nsproxy->uts_ns != <initial uts_ns>, where the initial namespace is captured at module init (before any unshare), avoiding any dependency on init_uts_ns being exported. Because we anchor on the initial namespace, firmware that re-unshares its own namespace stays in scope (it's still != initial).

UTS was chosen as a pure marker: zero filesystem/network/IPC/pid side effects, so /igloo/shared and hyperfs are untouched.

Changes

  • portal/scope.{c,h}igloo_scope_init() (capture initial uts_ns), igloo_in_scope(), igloo_scope_set_enabled(), and a set_scope_enabled portal op. Gating defaults off, so a new driver paired with an old Penguin that never enables scoping behaves exactly as before.
  • hooks/syscalls_hc.{c,h} — new per-hook scope_filter_enabled flag, checked in syscall_matches_hook alongside the existing pid/comm filters. Penguin sets it on read-only logging hooks; intervention hooks leave it clear so they still apply to every process (and the portalcall transport / fastpath is untouched).
  • hooks/sock_hc.c — gate igloo_sock_bind/igloo_sock_release on igloo_in_scope(current).
  • igloo_hc.c — call igloo_scope_init() at module init.

Testing

Builds cleanly for all 19 arch/version combos (kernels 4.10 and 6.13). The peng image (with the matching Penguin host changes) boots and runs the full test_target with scoping enabled; every logger subtest (netbinds, env, ...) passes, confirming in-scope firmware processes are still captured. The new scope_filter_enabled struct field and SET_SCOPE_ENABLED enum propagate correctly into the host kffi ISF.

Paired with the Penguin host-side PR (init.sh unshare, scope pyplugin, scope_filter plumbing, core.analysis_scope).

Add an inherited in-scope marker so analysis (syscall/exec/read-write/bind
hypercalls) only covers the firmware-under-analysis process subtree, not
Penguin's own infrastructure (boot machinery, the backgrounded vpnguin/
console/guesthopper helpers, and call_usermodehelper spawns).

The marker is the UTS namespace: penguin/src/resources/init.sh unshares a
fresh UTS namespace for the real guest init at handoff, so the firmware
subtree (inheriting the namespace across fork/exec) lives outside the kernel's
initial namespace while all Penguin infrastructure stays in it. igloo_in_scope()
compares current's uts_ns against the initial namespace captured at module load
(no dependency on init_uts_ns being exported), so firmware that re-unshares its
own namespace stays in scope.

- scope.c/scope.h: igloo_scope_init() (capture initial uts_ns), igloo_in_scope(),
  igloo_scope_set_enabled(), and a set_scope_enabled portal op. Default disabled,
  so a driver paired with a Penguin that never enables scoping behaves as before.
- syscalls_hc: per-hook scope_filter_enabled flag, checked in syscall_matches_hook
  alongside the existing pid/comm filters. Logging (read-only) hooks set it;
  intervention hooks leave it clear so they still apply to every process.
- sock_hc: gate igloo_sock_bind/release on igloo_in_scope(current).
- igloo_hc: capture the initial namespace at module init (pre-handoff).
@lacraig2 lacraig2 merged commit 17e2d0d into main Jun 25, 2026
1 check passed
@lacraig2 lacraig2 deleted the scope-analysis-loggers branch June 25, 2026 13:54
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.

1 participant