scope: gate analysis emission to the firmware process subtree#84
Merged
Conversation
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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/guesthopperhelpers 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.shruns 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 viacall_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 oninit_uts_nsbeing 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/sharedand hyperfs are untouched.Changes
portal/scope.{c,h}—igloo_scope_init()(capture initialuts_ns),igloo_in_scope(),igloo_scope_set_enabled(), and aset_scope_enabledportal 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-hookscope_filter_enabledflag, checked insyscall_matches_hookalongside 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— gateigloo_sock_bind/igloo_sock_releaseonigloo_in_scope(current).igloo_hc.c— calligloo_scope_init()at module init.Testing
Builds cleanly for all 19 arch/version combos (kernels 4.10 and 6.13). The
pengimage (with the matching Penguin host changes) boots and runs the fulltest_targetwith scoping enabled; every logger subtest (netbinds, env, ...) passes, confirming in-scope firmware processes are still captured. The newscope_filter_enabledstruct field andSET_SCOPE_ENABLEDenum propagate correctly into the host kffi ISF.Paired with the Penguin host-side PR (init.sh unshare,
scopepyplugin,scope_filterplumbing,core.analysis_scope).