Tier-2 Kernel Enforcement¶
Authorised application boundary
Authorised application code is trusted. An authorised app can send out a secret it has copied or encoded. Current content checks do not provide a general guarantee against this disclosure or a malicious authorised app. Memory-read tests and a Ready agent do not prove copied/encoded-secret exfiltration prevention. Enforced NetworkPolicy can restrict destinations, but allowed traffic remains a channel. See Security Model.
CloudTaser classifies kernel environments into two enforcement tiers based on eBPF capability. This page documents the Tier-2 threat model, the data-leak window bounds for secondary vectors, active mitigations, and customer deployment guidance.
Research basis
This threat model describes the older reduced enforcement path researched in cloudtaser-ebpf#606 (2026-06-04). Its latency figures came from historical GKE COS measurements. They do not classify current COS deployments: on 29 October COS 6.12.105+ reported Tier 1 lsm+fmod_ret and passed default strict readiness. See the recorded cohort.
Kernel Tier Definitions¶
Tier-1 — the agent reports effective synchronous deny paths for its required vectors using BPF LSM, fmod_ret or kprobe override. Check actual attachments, vector states and readiness; a tier is not proof of protection against arbitrary guest-kernel code.
Tier-2 — active BPF LSM protects covered paths, but required secondary vectors lack a synchronous deny mechanism. Absence of CONFIG_BPF_KPROBE_OVERRIDE alone does not imply Tier 2: fmod_ret can supply those paths, as measured on COS. Check the running agent instead of classifying by distribution name.
| Tier | Kernel capability | Examples | Primary enforcement |
|---|---|---|---|
| Tier-1 | Active BPF LSM with effective synchronous paths via LSM, fmod_ret or kprobe override |
Measured COS 6.12.105+ via lsm+fmod_ret; qualify other nodes |
Synchronous deny for reported required vectors |
| Tier-2 | Active BPF LSM with remaining secondary-vector gaps | Depends on the deployed kernel and agent; not a distribution-wide guarantee | Synchronous LSM deny on covered paths + reactive response on remaining vectors |
Check your kernel tier
# Check one possible synchronous mechanism; this alone does not set the tier
zcat /proc/config.gz | grep CONFIG_BPF_KPROBE_OVERRIDE
# Compiled LSM capability; also confirm bpf in /sys/kernel/security/lsm
zcat /proc/config.gz | grep CONFIG_BPF_LSM
# cloudtaser CLI
cloudtaser-cli status --enforcement-tier
Tier-2 Enforcement Model¶
On Tier-2 kernels, CloudTaser operates at two enforcement levels.
Synchronous LSM Denial (primary enforcement)¶
BPF LSM hooks intercept system calls before they execute. No data is read; the attacker receives an error immediately.
| Hook | Vectors blocked | Return value |
|---|---|---|
lsm_ptrace_access_check |
process_vm_readv, process_vm_writev, ptrace(PTRACE_ATTACH), ptrace(PTRACE_SEIZE) |
-EPERM |
lsm_file_open |
Opens of /proc/<pid>/environ, /proc/<pid>/mem, /proc/<pid>/maps, /proc/<pid>/pagemap, /proc/<pid>/smaps, /proc/<pid>/stack, /proc/<pid>/syscall, /dev/mem, /dev/kmem, /proc/kcore |
-EPERM |
Attacker calls process_vm_readv(target_pid, ...)
→ lsm_ptrace_access_check BPF hook fires BEFORE syscall executes
→ Hook checks caller against protected cgroup-array
→ Returns -EPERM
→ No memory is read
→ Event logged: VMREADV_DENIED
Primary vectors are zero-data-leak denials
process_vm_readv and /proc/<pid>/mem are the principal memory-read attack vectors. Both are denied synchronously by BPF LSM hooks on Tier-2. The attacker receives an error; no data is transferred.
Asynchronous ReactiveKill (secondary enforcement)¶
Eight syscall families have no BPF LSM hook in the supported kernel matrix. On Tier-2, the agent attaches via tracepoints, detects the violation at syscall-exit, and sends SIGKILL from userspace. The syscall completes before the signal arrives.
| Syscall family | Attack scenario | Mechanism |
|---|---|---|
io_uring_* |
Bypasses per-syscall eBPF hooks via submission queue | Tracepoint + SIGKILL |
userfaultfd |
Page-fault interception for controlled memory read | Tracepoint + SIGKILL |
copy_file_range |
In-kernel zero-copy between files | Tracepoint + SIGKILL |
kcmp |
Process comparison to fingerprint targets | Tracepoint + SIGKILL |
process_madvise |
Advise changes on another process's memory | Tracepoint + SIGKILL |
init_module / finit_module |
Kernel module load for privilege escalation | Tracepoint + SIGKILL |
setns |
Namespace escape | Tracepoint + SIGKILL |
splice / tee / sendfile / vmsplice |
Zero-copy data exfiltration | Tracepoint + SIGKILL |
ReactiveKill has a data-leak window
The syscall completes before SIGKILL is delivered. The window is bounded by ring-buffer flush latency + Go goroutine scheduling + signal delivery — measured at approximately 5ms on GKE COS nodes.
Worst-Case Data-Leak Window Analysis¶
Theoretical maximum¶
At sendfile(2) throughput (~10 GB/s kernel-to-kernel), a theoretical maximum of ~50 MB could be transferred in one syscall before the SIGKILL arrives.
Practical exposure¶
The theoretical maximum does not reflect realistic attack conditions:
-
memfd_secretmakes primary vectors unreachable. Secrets in the wrapper are stored inmemfd_secret-backed memory (kernel 5.14+). This memory is removed from the kernel direct map —process_vm_readvreturnsEIOagainst these pages regardless of LSM enforcement. The LSM hook is defense-in-depth on top of hardware-level isolation. -
ReactiveKill vectors are secondary side-channels. The kprobe-only vector families (
splice,sendfile,io_uring, etc.) are not direct memory-read paths. They require the attacker to already have data in a buffer they control — an authorised app already has access to its delivered secrets and may copy or encode them without a separate external read. Primary read-path denial does not prevent that disclosure. -
Heap zeroing closes the transient plaintext window. Wrapper v0.2+ zeros Go heap copies of secrets immediately after use. A successful read of wrapper heap during the fetch window returns zeroed or partial plaintext.
-
Seccomp-bpf blocks vector creation at pod admission. The operator injects a RuntimeDefault seccomp profile that blocks
process_vm_readv,pidfd_getfd, anduserfaultfdat the kernel syscall filter level for attacker pods.
Window summary¶
| Scenario | Data-leak window | Notes |
|---|---|---|
Primary vectors (process_vm_readv, /proc/mem) |
None — synchronous LSM denial | BPF LSM hook fires before syscall |
Secondary vectors (splice, sendfile, io_uring) |
~5ms ReactiveKill window | memfd_secret pages still inaccessible inside window |
| Theoretical worst case (no mitigations) | ~50 MB per call | Not achievable: memfd + seccomp + heap-zeroing |
Active Mitigations on Tier-2¶
| Mitigation | Status | Effect |
|---|---|---|
memfd_secret (kernel 5.14+) |
Active by default | Hardware-level page hiding; process_vm_readv returns EIO against secret pages |
| Heap zeroing | Active (wrapper v0.2+) | Transient Go heap copies zeroed after use; reduces plaintext exposure during fetch window |
| Seccomp-bpf (RuntimeDefault) | Active via operator injection | Blocks process_vm_readv, pidfd_getfd, userfaultfd on attacker pods at admission |
| BPF LSM (primary enforcement) | Active on Tier-2 | Synchronous denial of all primary memory-read vectors |
| ReactiveKill (secondary enforcement) | Active on Tier-2 | ~5ms kill window for secondary vectors |
| Kernel upgrade to Tier-1 | Optional | Restores synchronous denial for all vectors including secondary families |
Customer Guidance¶
Default readiness policy¶
Readiness under the default chart
The default chart refuses readiness while a required enforcement gap remains. Synchronous paths may use LSM, fmod_ret or kprobe override; ReactiveKill alone does not satisfy this gate. The measured COS deployment passed the default strict settings without accepting gaps. A deployment with remaining required gaps still returns HTTP 503. See Kernel Compatibility.
Tier-2 enforcement provides synchronous denial for all primary secret-access vectors. The ~5ms ReactiveKill window applies only to secondary side-channel vectors that are not direct memory-read paths. Combined with memfd_secret and heap zeroing, this provides strong practical protection for regulated workloads.
Zero-tolerance posture¶
For workloads requiring synchronous denial on every vector without exception:
- Select a node/release cohort with active BPF LSM and effective synchronous paths for the required vectors.
- Inspect the agent's
/statuskernel_tier, mechanism and per-vector reports using its configured TLS and authentication. - Require
/readyzto pass under the default strict policy with no accepted or unaccepted gaps. Retain the exact node image and release evidence.
Verify your enforcement tier¶
Use the node verification procedure.
The measured COS agent reported kernel_tier: "1",
enforcement_mode: "lsm+fmod_ret", lsm_active: true and
override_available: false. Inspect vector states and readiness alongside the
tier; do not require kprobes to be active when another synchronous path is effective.
Enforcement tier is reported in audit events
Every enforcement event logged by the agent includes the enforcement_mode field. This allows compliance teams to verify that the declared tier matches the observed behaviour in audit logs.