You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Environment: kernel 6.6.102+ (Alinux), root, BPF-LSM active (capability,yama,bpf)
Symptom
A freshPinnedEngine::open_or_install_singleton() (i.e. no pre-existing pin under /sys/fs/bpf/actplane/v1) fails to load on kernel 6.6:
trace_openat_exit.load: the BPF_PROG_LOAD syscall failed. Verifier Output:
combined stack size of 5 calls is 544. Too large
This blocks ActPlaneBackend::open() entirely — the enforcement stack cannot start on 6.6 unless a pin from an older, smaller object happens to survive on the host.
Evidence
Reproduced with three prebuilt generations, all failing identically on 6.6:
f0b5015c0 (current main, full + inode-only variants)
a freshly rebuilt object via the documented Makefile pipeline (clang 17, 6.6 vmlinux.h, bpftool gen object)
Note the variant selection already works as designed on 6.6: object_bytes() returns the inode-only object there (kernel < 7.1), and the failure comes from that inode-only object's trace_openat_exit — -DINODE_GUARD_ONLY guards the LSM path machinery (bpf_d_path), not the sys_exit_openat tracepoint program, so the deep call chain is compiled into both variants.
f0b5015c0's commit message states "Verified on 47.111.114.232 (Alinux4 / kernel 7.1.10)" — the full fresh-install path on 5.10/6.6 appears untested. Historical e2e runs on a 6.6 host passed only because they reused a singleton pinned by an older object; once the pin is removed (as any fresh deployment or clean CI runner would be), the load fails.
A minimal-profile Loader::load(empty_config) (Core tracepoints only, trace_openat_exit not attached) loads fine on 6.6 — the failure is specific to the heavyweight file-IO programs.
Impact
Fresh enforcer deployment on 5.10/6.6 hosts fails at startup (loudly — not a silent failure, but a functional gap vs the stated kernel support matrix).
Reduce trace_openat_exit call-chain stack depth on 6.6 (5 calls summing to 544 bytes vs the 512-byte limit; 7.1 allows more). The 6.6 verifier output lists the per-frame budget as 0+216+8+96+152+0+0+0+... — the 216-byte frame is the first candidate to split or slim. Selecting the inode-only object does not help since both variants carry the same tracepoint program.
Reproduction
sudo rm -rf /sys/fs/bpf/actplane/v1 # ensure fresh install
# then any engine open, e.g. ActPlaneBackend::open() or the #3264 test harness
Status update after re-testing on main @ 89a2258a2 (includes 3fefd1364): the default full-profile fresh install is still broken on 6.6 — but the agent-file-guard profile now works.
Two runs on the same host (kernel 6.6.102, root, BPF-LSM active, pin root removed before each), using the prebuilt objects committed on main:
Default profile (PinnedEngine::open_or_install_singleton() with no env → HookReserve::pinned_profile() → full_profile): FAILS with the same verifier rejection as originally reported —
trace_openat_exit.load: the BPF_PROG_LOAD syscall failed. Verifier output:
combined stack size of 5 calls is 544. Too large
ACTPLANE_PINNED_PROFILE=agent-file-guard: the fresh singleton install SUCCEEDS — 3fefd1364's #ifdef INODE_GUARD_ONLY dual-variant build does fix this path (LSM-only profile never loads trace_openat_exit).
The catch: nothing in the repo sets ACTPLANE_PINNED_PROFILE — not the enforcer crate, not the systemd units, not the docs (grep is clean). ActPlaneBackend::open() goes through open_or_install_singleton() → default full_profile, so a production enforcer on a clean 5.10/6.6 host still fails at startup unless the deployment exports that env manually.
So the remaining gap is narrower than the original report: only the full-profile program set (trace_openat_exit's 544-byte call chain vs the 512-byte limit on 6.6) needs a fix — either a stack-depth reduction, or making the enforcer path default to / explicitly select the agent-file-guard profile on kernels < 7.1. Keeping this open for that decision.
Recurrence confirmed in AgenticOS Nightly 2026-09-23 (run nightly-20260923-020120, ALinux 4 ECS 8.218.234.88, kernel 6.6.102-6.2.alnx4, agentsight 0.13.0): the new v0.13.0 inode-guard tests test_v0130_enforcement_inode_guard.py fail with 503 enforcer_unavailable on /api/enforcement/health.
Root cause on this host is the same 6.6 start failure, surfaced through two symptoms:
Fresh/clean install path reproduces the reported verifier error verbatim: trace_openat_exit.load: BPF_PROG_LOAD failed. combined stack size of 5 calls is 544. Too large
This is because pinned_engine_present() (ebpf-ifc-engine/src/lib.rs L594-644) unconditionally requires the two 0.13.0-added maps cap_pending_submitter and te_inode_guard; when they are absent from the pin root the check returns Ok(false) (L609-611), which re-enters load_with_pinned_layout → pin_loaded_maps (L486-501) → map.pin() on the maps that are present → EEXIST. The incomplete pin root (missing only those two maps) is the residue of the upgrade/install aborted by the verifier failure above.
Consequence (vs the fail-closed contract in actplane.rs health() L427-429): the enforcer never reaches a steady state, so /api/enforcement/health hard-503s instead of reporting file_delete_guard=false + ready=true. cat /sys/kernel/security/lsm on this host = capability,landlock,yama,lua,bpf (bpf present), so this is not a missing-BPF-LSM case.
Suggest also treating a pin root missing newly-required maps as "schema mismatch → remove/rebuild pin root" (same path as the existing marker-mismatch branch at L613-619), rather than Ok(false).
@zhangtaibo — your nightly finding closes the loop on both defect classes, and both already have fixes in flight or merged:
The crash-loop (EEXIST on re-pin) is the stale-pin-root class — already fixed on main. I reproduced exactly this failure mode synthetically on 09-21 (fresh install, then removed one newly-required map from the pin root → pinned_engine_present counts the engine absent → reinstall attempt → pin map ts_proc at ...: BPF_OBJ_PIN failed on the first colliding map — the same EEXIST your RPM deployment hits 2700+ times). Your suggestion (treat a pin root missing newly-required maps as a rebuild scenario, not a crash) landed as #3446 (merged): pinned_engine_present now encodes marker/profile/schema mismatches as InvalidData, and open_or_install_singleton self-heals both the incomplete-root and incompatible-revision cases via remove_stale_pin_root() + clean reinstall — with a layout guard so a misconfigured ACTPLANE_BPF_PIN_ROOT can't cause data loss. a29e4cd5b then ported it into the attested-build path as patch 0008-clean-stale-pin-root.patch, so the RPM/attested artifact self-heals too. The first nightly built from current main should show the upgrade path recovering with a WARN instead of crash-looping.
The verifier stack overflow (544 > 512 on 6.6) — your verbatim reproduction matches the original report. The stack-depth fix is in flight as #3456 (fits the openat/rename/mremap exit chains back under the 512 limit); once it merges, a nightly's fresh-install path should go ready directly instead of needing the agent-file-guard profile workaround.
Activity
github-actions commentedon Sep 14, 2026
🔀 Issue Router
sight99%问题涉及 AgentSight 的 PinnedEngine 在 6.6 内核加载 BPF 程序时的 verifier 栈溢出。
Evidence: 标题和正文均明确指向 AgentSight/agentsight,且涉及 PinnedEngine、trace_openat_exit 与 BPF 加载。
This routing was applied by the ANOLISA Issue Router through GitHub Actions.
jfeng18 commentedon Sep 15, 2026
Status update after re-testing on main @
89a2258a2(includes3fefd1364): the default full-profile fresh install is still broken on 6.6 — but theagent-file-guardprofile now works.Two runs on the same host (kernel 6.6.102, root, BPF-LSM active, pin root removed before each), using the prebuilt objects committed on main:
PinnedEngine::open_or_install_singleton()with no env →HookReserve::pinned_profile()→full_profile): FAILS with the same verifier rejection as originally reported —ACTPLANE_PINNED_PROFILE=agent-file-guard: the fresh singleton install SUCCEEDS —3fefd1364's#ifdef INODE_GUARD_ONLYdual-variant build does fix this path (LSM-only profile never loadstrace_openat_exit).The catch: nothing in the repo sets
ACTPLANE_PINNED_PROFILE— not the enforcer crate, not the systemd units, not the docs (grep is clean).ActPlaneBackend::open()goes throughopen_or_install_singleton()→ defaultfull_profile, so a production enforcer on a clean 5.10/6.6 host still fails at startup unless the deployment exports that env manually.So the remaining gap is narrower than the original report: only the full-profile program set (
trace_openat_exit's 544-byte call chain vs the 512-byte limit on 6.6) needs a fix — either a stack-depth reduction, or making the enforcer path default to / explicitly select theagent-file-guardprofile on kernels < 7.1. Keeping this open for that decision.zhangtaibo commentedon Sep 22, 2026
Recurrence confirmed in AgenticOS Nightly 2026-09-23 (run nightly-20260923-020120, ALinux 4 ECS 8.218.234.88, kernel 6.6.102-6.2.alnx4, agentsight 0.13.0): the new v0.13.0 inode-guard tests
test_v0130_enforcement_inode_guard.pyfail with503 enforcer_unavailableon/api/enforcement/health.Root cause on this host is the same 6.6 start failure, surfaced through two symptoms:
Fresh/clean install path reproduces the reported verifier error verbatim:
trace_openat_exit.load: BPF_PROG_LOAD failed. combined stack size of 5 calls is 544. Too largeDefault RPM deployment (
ACTPLANE_PINNED_PROFILE=credential-exfiltration) crash-loops (NRestarts2700+,Restart=always) with:Error: kernel enforcement failed: open pinned singleton: pin map <map> at /sys/fs/bpf/actplane/v1/maps/<map>: BPF_OBJ_PIN failedThis is because
pinned_engine_present()(ebpf-ifc-engine/src/lib.rs L594-644) unconditionally requires the two 0.13.0-added mapscap_pending_submitterandte_inode_guard; when they are absent from the pin root the check returnsOk(false)(L609-611), which re-entersload_with_pinned_layout→pin_loaded_maps(L486-501) →map.pin()on the maps that are present →EEXIST. The incomplete pin root (missing only those two maps) is the residue of the upgrade/install aborted by the verifier failure above.Consequence (vs the fail-closed contract in actplane.rs
health()L427-429): the enforcer never reaches a steady state, so/api/enforcement/healthhard-503s instead of reportingfile_delete_guard=false+ready=true.cat /sys/kernel/security/lsmon this host =capability,landlock,yama,lua,bpf(bpf present), so this is not a missing-BPF-LSM case.Suggest also treating a pin root missing newly-required maps as "schema mismatch → remove/rebuild pin root" (same path as the existing marker-mismatch branch at L613-619), rather than
Ok(false).fix(sight): fit ActPlane progs into 6.6 stack limit
jfeng18 commentedon Sep 28, 2026
@zhangtaibo — your nightly finding closes the loop on both defect classes, and both already have fixes in flight or merged:
The crash-loop (EEXIST on re-pin) is the stale-pin-root class — already fixed on main. I reproduced exactly this failure mode synthetically on 09-21 (fresh install, then removed one newly-required map from the pin root →
pinned_engine_presentcounts the engine absent → reinstall attempt →pin map ts_proc at ...: BPF_OBJ_PIN failedon the first colliding map — the same EEXIST your RPM deployment hits 2700+ times). Your suggestion (treat a pin root missing newly-required maps as a rebuild scenario, not a crash) landed as #3446 (merged):pinned_engine_presentnow encodes marker/profile/schema mismatches asInvalidData, andopen_or_install_singletonself-heals both the incomplete-root and incompatible-revision cases viaremove_stale_pin_root()+ clean reinstall — with a layout guard so a misconfiguredACTPLANE_BPF_PIN_ROOTcan't cause data loss.a29e4cd5bthen ported it into the attested-build path as patch0008-clean-stale-pin-root.patch, so the RPM/attested artifact self-heals too. The first nightly built from current main should show the upgrade path recovering with a WARN instead of crash-looping.The verifier stack overflow (544 > 512 on 6.6) — your verbatim reproduction matches the original report. The stack-depth fix is in flight as #3456 (fits the openat/rename/mremap exit chains back under the 512 limit); once it merges, a nightly's fresh-install path should go ready directly instead of needing the
agent-file-guardprofile workaround.