Back to Blog & Resources
Detection engineering · Linux kernel · Evidence

Kernel Detection Engineering: From Syscalls to Defensible Evidence

Translate syscalls, LSM hooks and kernel telemetry into evidence-backed detections, with malware behavior analysis, sysctl review and an interactive investigation graph.

Riad DAHMANIK8SEC Security ResearchRevised and consolidated October 20, 2026Malware behavior · Telemetry · Investigation
Conceptual Linux kernel architecture chart: user space, system-call interface, kernel subsystems and hardware; clarified in the article.
Supplied kernel architecture illustration. The layered model below corrects its simplified HAL and linear-flow assumptions.

K8SEC / KERNEL DETECTION MODEL

Watch the kernel operation, then prove the effect

The operation has a lifecycle: userspace request → kernel entry → object resolution → LSM decision → return value → Tetragon event → workload enrichment → independent API evidence → analyst conclusion. Hook placement decides what is visible. A kprobe at entry can show intent before authorization; a return probe can establish the interface result; an LSM hook can show an authorization point; none by itself reconstructs the complete attack path.

Architecture: three evidence planes, two identity boundaries, one adjudication gate
Workload / process planeUntrusted input → application process → exec or memory operation. Record binary digest, parent exec ID, Pod UID and container ID.Boundary A: process request ≠ successful kernel effect
Kernel / Tetragon planeSyscall, kprobe, tracepoint or LSM hook → selector → event with hook, arguments and result where available. Check policy load and event loss.Boundary B: sensor event ≠ malicious intent or independent enforcement
API / control planeAuthenticated Kubernetes or OpenShift request → authorization → audit stage and status → resulting object state. A ServiceAccount is not a Linux PID.Separate source: API audit is not a syscall recorder
Correlation gate · cluster + event-time Pod/container identity + process lineage + bounded time + accepted result + independent source attribution. Missing or contradictory fields remain unknown.

Solid sequence = records present in the synthetic example. A displayed join is conditional; it does not prove causation. These are research diagrams, not live telemetry.

Four paths through the same evidence architecture

Select a path. The graph changes, but the conclusion never jumps from a sensor event straight to malware or escape. This is a synthetic exercise, not a live detector dashboard.

R03 · staged execution is a hypothesis, not a malware verdict

Observed
In the synthetic trace, N03 sees an execve request from a writable path, N04 sees memfd creation, and N06 sees a process-name change in that order within 180 seconds.
Join gate
Require the same cluster and Pod UID, event-time container identity, then inspect exec IDs and parent/child lineage. The shared Pod alone cannot prove one process performed all three actions.
Benign alternative
A compiler or update worker can stage a temporary executable and allocate anonymous files. A Java process can rename itself for legitimate diagnostics.
Next evidence
Pair entry with result, inspect image digest and executable provenance, compare with the approved workload baseline, and establish whether the anonymous object was executed.

R01 · credential access and accepted cross-namespace placement

Observed
A Tetragon file-permission event is followed by an API audit record for an accepted, non-dry-run cross-namespace Pod create within 120 seconds.
Join gate
Resolve a unique source Pod at request time, verify direct source-IP attribution rather than proxy/NAT inference, and match the effective ServiceAccount. A shared SA name or close timestamps alone are insufficient.
Still unknown
File access is not proof that a token was copied or used by this process. An accepted API request is not proof that the Pod reached Running or that code executed there.
Negative control
If the source IP maps to several Pods, the caller is a controller, the API operation is denied, or the request is dry-run, do not promote this to the cross-plane candidate.

R05 · three denied requests do not make a container escape

Observed
A same-Pod sequence requests setns, mount and a BPF operation within 90 seconds. In this control fixture all results are denied.
Decision
Report boundary-sensitive probing and the negative results. Do not call host access, kernel compromise, or successful privilege escalation.
Next evidence
For a success claim, establish return values, effective capabilities, relevant namespace IDs, the host object reached, and an independently observed host-side effect.
Coverage caveat
N21 raw syscall mapping can duplicate these signals; duplicate events do not count as independent stages. A missing event may reflect hook or collector loss.

Approved build worker · an expected signal is a negative control

Observed
A signed, scheduled build job executes a temporary build helper under an expected parent and image digest.
Decision
The N03 signal still exists, but the owner-approved job and executable provenance explain it. Keep the raw event; suppress only the narrow workload context after review.
Regression test
Change the parent, image digest, namespace or time window. The same broad exception must no longer match. If it does, the exception is unsafe.
Limit
An approved identity does not make every later action benign; a successful sensitive API operation needs its own authorization review.

Instrumentation choice is part of the detection claim

Kernel observation points and evidence limits
PointGood forBlind spot / stabilityVerification
Syscall entry / tracepointArchitecture-specific operation request, arguments and attempted sequence.An entry event precedes the result; a library call can map to another interface or no syscall.Pair invocation and return, test denied and permitted controls, inspect ABI and event loss.
kprobe / fentrySelected internal kernel function and object context.Internal symbols and arguments vary by kernel/build; observing a function is not a stable user ABI.Confirm BTF/symbol support on every node image and compare against a canary.
LSM hookSecurity-relevant subject/object decision point such as file permission or socket connect.One hook does not represent every authorization check or later effect.Identify the exact hook, object, policy and result; test allowed and denied paths.
Process lifecycle eventExecutable provenance, ancestry and event-time container context.A process start alone does not identify malicious purpose or a later API caller.Join stable exec and Pod identities; inspect image digest and expected workload behavior.
API auditAuthenticated actor, verb, resource, stage and server-side result.Not a syscall feed; actor SA may be shared; accepted API call does not prove downstream execution.Preserve auditID, stage, source provenance, resource UID and resulting object state.

Observe versus enforce: the supplied Tetragon design’s 31 N/C policies are Post-only. R01–R08 are correlation candidates built on top of normalized events. A purple “kill candidate” in that draft is not deployed protection. Any Sigkill or Override experiment needs separate workload scope, compatible kernel/hook, canary, rollback and approval; it does not undo an earlier API write.

For a rigorous finding, record the policy ID and version, loaded nodes, hook, selector, raw event ID, return/errno, process exec ID, event-time Pod UID, enrichment source, auditID if any, and the independent result. A missing join or sensor gap is unknown, not a negative detection. Compare duplicate policy families before interpreting a multi-step sequence as multiple independent behaviors.

References: Tetragon TracingPolicy reference · advanced process execution · kernel trace events · Kubernetes audit logging.

Linux container → shared-kernel model. Arrows show representative crossings, not a mandatory sequence for every operation.
  1. 01 · User spaceApplication and libraries inside a container. The image is a filesystem and process context, not a private kernel.Identity: UID/GID, capabilities, namespaces, cgroup, Pod/container UID.
  2. 02 · Entry and decisionSyscall, fault, interrupt or packet path enters privileged execution. Seccomp can filter syscall invocation; LSM checks are operation/object specific.Tracepoint/kprobe visibility is different from LSM enforcement and return status.
  3. 03 · Shared Linux kernelScheduler/process management ↔ memory management ↔ VFS/filesystems ↔ network stack ↔ drivers. These subsystems cooperate; there is no universal linear path.eBPF programs may attach at supported hooks after loader permission and verifier checks.
  4. 04 · Host and effectsCPU, RAM, storage and network interfaces; container-visible resources are constrained views of host-managed objects.Verify the returned result and independently observed host/API effect.
Cross-cutting constraintsnamespaces · cgroups · capabilities · seccomp · SELinux/LSM · admission/SCC

The supplied hero illustration uses a “HAL” band as a teaching shorthand. Linux does not require every syscall to traverse a single HAL layer; interrupts, page faults and receive paths can enter elsewhere. This diagram corrects that simplification.

Do not conflate filter and tracer: seccomp classic BPF filters syscall number, architecture and raw arguments before the handler; it does not resolve a pointed-to pathname. eBPF tracing or LSM instrumentation asks a different question and cannot by itself prove that a policy denied an operation. Kernel seccomp semantics.

01Speak precisely about the boundary

A syscall alert without a subject, an object and a result is a lead—not a finding. A web worker opening a socket, a debugger reading memory and an implant doing the same can produce superficially similar events. Detection engineering reconstructs the operation, establishes whether it belongs to the workload, and records the limits of the evidence.

This companion to K8SEC’s kernel-boundary guide moves from hardening to investigation. All traces in the interactive exercise are synthetic. The page does not collect host data, execute malware or claim that a production detector has been validated.

System call: an ABI request
A syscall is a controlled entry from userspace into kernel services. A C library wrapper is not necessarily one-to-one with a syscall: it can translate arguments, choose another interface or avoid a kernel transition. Record the architecture and ABI before interpreting syscall numbers. For an attacker, this is an operation to request; for a defender, it is an observation point, not intent.
LSM hookpoint: a policy opportunity
An LSM hook is a defined point where security modules can examine a relevant operation and, where the hook permits, influence authorization. Hooks see different objects and stages; there is no universal “one hook per syscall” relationship. A permission decision at one hook does not prove that every later check or effect succeeded.
Kernel function: an implementation step
A kernel C function may resolve a pathname, manage memory or operate a socket. Internal calls also originate from worker threads and other kernel activity. Function names and arguments depend on the build. Seeing a function execute is not equivalent to a userspace syscall or a completed security-sensitive operation.
“Syspath” and “C kernel call”
Neither is a distinct Linux security primitive. Here, a syspath means a sysfs object path under /sys; an execution path means the sequence through kernel code. A “C kernel call” might mean a libc wrapper, a direct syscall invocation or an internal C function call. Name the actual interface instead of treating these as interchangeable.

Three paths, three meanings: /sys/devices/… describes kernel objects and attributes; /proc/sys/kernel/… exposes kernel sysctl settings; a function call path describes execution. A path string alone does not capture a mount namespace, underlying object or permission decision. Sources: Linux syscall reference, sysfs documentation, LSM architecture (conceptual background; that page warns that its API descriptions are outdated).

Layered kernel architecture · execution, policy and observation
Conceptual Linux container model. Layers organize responsibilities; they are not independent security walls.
01 / USERSPACE
Container processCode, libraries, UID/GID, namespaces
Host processDifferent context · same host kernel

↓ request via syscall ABI ↑ result / errno

USER ↔ KERNEL PRIVILEGE BOUNDARYArchitecture-specific entry / dispatch / return · configured entry controls, including seccomp
02 / SHARED KERNEL · INTERCONNECTED SUBSYSTEMS
VFS + filesystemsPaths → objects → file operations
Memory managementMappings · page cache · faults
Network stackSockets · protocol processing
Scheduler + tasksCPU execution · waits · wakeups
Cross-cutting authorization, not a final layerCredentials / permissions / capabilities / relevant LSM hooks act at operation-specific points. Namespaces shape views; cgroups account for and control resources.
Cross-cutting observation, not automatic enforcementTracepoints · eligible function probes · supported eBPF attachments → events for a userspace collector. Coverage varies; early entry code can be non-instrumentable.

↓ backing operations when needed ↑ completion / interrupt

03 / DRIVERS + HARDWARE
Device / driver pathsStorage · network · platform devices
CPU + memoryExecution · address translation
Observation branch → collector → correlation → analystKeep event identity, return semantics and loss counters. The telemetry pipeline is not an extra execution layer that every operation must traverse.
Read the diagram as an architecture, not a literal call stack

Conventional containers share the host kernel. A file operation can involve both VFS and memory management; network and device events may run in asynchronous contexts. The diagram does not imply that every syscall visits every subsystem, that hardware I/O is always necessary, or that one LSM hook explains all authorization.

Architecture references: entry and exit handling, memory-management concepts. Conventional container assumptions do not automatically apply to VM-backed runtimes.

Infer the behavior from an evidence chain. Never infer malware merely from the name of an API.

02Choose sensors by the question they can answer

The following flow is conceptual, not a mandatory ordering for every subsystem. Several policy checks, asynchronous operations and object lifetimes may intervene.

  1. User intent → ABI

    Wrapper, syscall number, arguments and calling task.

  2. Kernel operation → policy

    Resolved object, relevant LSM checks and subsystem execution.

  3. Result → evidence

    Return status, subsequent effect and collector health.

Dynamic syscall lifecycle · openat()

Step through a simplified regular-file open. This is a teaching model, not a captured stack trace. Lookup, filesystem methods and policy checks can interleave; exact symbols and ordering vary by kernel, filesystem and flags.

All conceptual paths are shown. No kernel operation is executed.

Open allowed

  1. 01User requestStep 1
  2. 02Kernel entryStep 2
  3. 03Resolve objectStep 3
  4. 04Evaluate accessStep 4
  5. 05Establish handleStep 5
  6. 06Return fd = 3Step 6
Step 1 · User request
Userspace
Application asks to open /training/report.txt read-only. The wrapper supplies a directory context and flags; the string is still untrusted input.
Detection interpretation
Observe caller identity and requested arguments. Do not yet claim an object was opened.
Step 2 · Kernel entry
ABI boundary
The architecture-specific entry path dispatches the syscall. Configured entry-time controls may reject a request before deeper work.
Detection interpretation
A syscall-entry event proves invocation, not completion. This scenario assumes the request passes entry controls.
Step 3 · Resolve object
VFS / namespace
Path lookup uses the task’s root, working directory or directory descriptor, mounts and filesystem objects. A pathname does not identify a global host file.
Detection interpretation
Preserve mount namespace and resolved object context. Checks can happen during lookup, not only at the next illustrated node.
Step 4 · Evaluate access
Authorization boundary
Relevant permissions and LSM checks are evaluated. Here they permit this open; this is not a grant for every later operation.
Detection interpretation
A particular allow decision is not proof that all checks passed or that the operation completed.
Step 5 · Establish handle
Open-file state
The successful open establishes an open file description and a descriptor in the process. The illustrative descriptor is 3.
Detection interpretation
Correlate the handle with its underlying object and lifetime. The number 3 will be reusable after close.
Step 6 · Return fd = 3
Kernel → userspace
The caller receives a nonnegative descriptor. File content has not been read by this open alone.
Detection interpretation
Supported claim: this open succeeded. Reading bytes requires a separate operation and result.

Access denied

  1. 01User requestStep 1
  2. 02Kernel entryStep 2
  3. 03Resolve objectStep 3
  4. 04Reject accessStep 4
  5. 05Return -1 / EACCESStep 5
Step 1 · User request
Userspace
The same read-only file-open request is made by a different effective security context.
Detection interpretation
Compare identities and policy context, not just the identical pathname.
Step 2 · Kernel entry
ABI boundary
This illustrative request passes entry controls and reaches filesystem processing.
Detection interpretation
Entry visibility does not prove that later authorization will allow access.
Step 3 · Resolve object
VFS / namespace
The scenario reaches the relevant object after lookup. Earlier lookup denials are also possible in real systems.
Detection interpretation
Do not assume every EACCES means this same lookup stage was reached.
Step 4 · Reject access
Authorization boundary
A relevant access check denies this modeled request. No successful descriptor is returned.
Detection interpretation
A return error alone cannot distinguish DAC from a specific LSM denial; obtain the relevant policy evidence.
Step 5 · Return -1 / EACCES
Kernel → wrapper
The wrapper exposes failure and errno. The successful-handle stage is absent from this scenario.
Detection interpretation
Supported claim: this request did not produce a successful open. It does not prove the host is clean.

Object not found

  1. 01User requestStep 1
  2. 02Kernel entryStep 2
  3. 03Lookup failsStep 3
  4. 04Return -1 / ENOENTStep 4
Step 1 · User request
Userspace
The caller requests a regular file that does not exist in this scenario’s visible namespace.
Detection interpretation
The same string can resolve differently for another task or mount namespace.
Step 2 · Kernel entry
ABI boundary
The request enters kernel handling and proceeds to lookup.
Detection interpretation
A seen syscall still has no known successful effect.
Step 3 · Lookup fails
Resolution boundary
A required path component is missing in this synthetic path.
Detection interpretation
Distinguish a resolution failure from an authorization control deliberately blocking access.
Step 4 · Return -1 / ENOENT
Kernel → wrapper
The wrapper reports the missing-path result. Later open and descriptor-success stages are not reached.
Detection interpretation
Supported claim: failure for this path resolution. This is not evidence that a security policy worked.

Lifecycle semantics: open/openat reference. The error values shown here are wrapper-level conventions; a kernel event may encode errno differently.

Inside the kernel · a buffered regular-file read

Start with an already-open, readable regular-file descriptor. Compare a simplified cached read, storage-backed read and rejected read. These are not universal paths for sockets, device files, direct I/O or asynchronous I/O.

All conceptual paths are shown. No kernel operation is executed.

Page-cache hit

  1. 01read(fd, buffer, count)Step 1
  2. 02Resolve file + validateStep 2
  3. 03Dispatch file operationStep 3
  4. 04Use cached dataStep 4
  5. 05Transfer + return 64Step 5
Step 1 · read(fd, buffer, count)
ABI boundary
The process requests bytes through an existing descriptor.
Detection interpretation
The descriptor number is meaningful only inside the correct descriptor-table and lifetime context.
Step 2 · Resolve file + validate
VFS / access boundary
Kernel handling resolves the open file, checks suitability and performs relevant access checks before this modeled transfer.
Detection interpretation
A previous successful open does not prove every later read succeeds.
Step 3 · Dispatch file operation
Filesystem boundary
The implementation associated with the open file handles the request. For this example, it is a buffered regular-file read.
Detection interpretation
Trace the actual implementation on the target build; do not universalize one internal function name.
Step 4 · Use cached data
Memory subsystem
The requested data is available in the page cache in this simplified case. No new storage read is required to satisfy it.
Detection interpretation
No matching disk event does not disprove a file read.
Step 5 · Transfer + return 64
Result boundary
The caller receives 64 bytes in this synthetic result. A short read is possible; zero can indicate end-of-file.
Detection interpretation
Bytes transferred do not establish the content’s sensitivity, malicious intent or later exfiltration.

Page-cache miss

  1. 01read(fd, buffer, count)Step 1
  2. 02Resolve file + validateStep 2
  3. 03Dispatch file operationStep 3
  4. 04Request storage + waitStep 4
  5. 05Transfer + return 64Step 5
Step 1 · read(fd, buffer, count)
ABI boundary
The same kind of read request enters kernel handling.
Detection interpretation
Retain caller and invocation identity across subsequent events.
Step 2 · Resolve file + validate
VFS / access boundary
The open file and relevant access conditions are checked for this modeled request.
Detection interpretation
Different filesystem types and states can take different paths.
Step 3 · Dispatch file operation
Filesystem boundary
The buffered regular-file implementation needs data that is not currently available in cache.
Detection interpretation
Kernel operations may fan out; one request is not necessarily one block-device event.
Step 4 · Request storage + wait
I/O / scheduling boundary
The filesystem arranges backing I/O; the requesting task may sleep while work progresses and completion makes data available.
Detection interpretation
Do not attribute every worker or completion event by the worker’s PID alone. Preserve request/object relationships.
Step 5 · Transfer + return 64
Result boundary
This synthetic operation completes and transfers 64 bytes to the caller.
Detection interpretation
Latency and storage activity add context; the read result, not an I/O request alone, establishes this transfer.

Read rejected

  1. 01read(fd, buffer, count)Step 1
  2. 02Access check rejectsStep 2
  3. 03Return -1 / EACCESStep 3
Step 1 · read(fd, buffer, count)
ABI boundary
The read is requested through an existing descriptor.
Detection interpretation
A valid descriptor and a prior open do not by themselves guarantee this operation is permitted.
Step 2 · Access check rejects
Policy boundary
A relevant access check rejects this modeled operation before the file-data transfer.
Detection interpretation
Identify the actual rejecting control using its decision evidence; the diagram does not infer it from errno.
Step 3 · Return -1 / EACCES
Result boundary
This fixture reports failure without a successful transfer.
Detection interpretation
This does not imply a universal one-check read path or prove that other requests were blocked.

Operation references: VFS object and operation model, read results and page cache.

Observation points and the claims they support
PointUseful evidenceDo not conclude
Syscall entry / exitArguments at entry; completion or failure from the corresponding return. Pair by task and invocation.Entry proves success; pathname arguments are resolved object identities.
TracepointA deliberately instrumented event and its advertised fields. Discover actual event names and formats on the target.Every kernel build has the same event schema or every relevant event is enabled.
kprobe / kretprobeExecution at eligible implementation locations and returns. Useful when a higher-level event omits required context.Function names, prototypes and offsets are portable contracts.
LSM / BPF LSMOperation-specific object and policy context; supported hook return contracts can enable enforcement.Loading a tracing BPF program automatically blocks the operation.
Userspace tracerA controlled workload’s calls, returns, signals and children when configured.Unperturbed timing, kernel-wide visibility or zero exposure of sensitive arguments.

eBPF is an execution mechanism for programs attached to supported hooks. The attachment type and program logic determine whether it observes, transforms or participates in enforcement. A BPF LSM policy must respect its hook’s semantics and preserve an existing denial where the contract requires it. A tracing probe should not be advertised as an authorization control. For example, an inode-permission hook addresses filesystem permission checks; an execution-related hook examines a different stage. Do not use either as a substitute for a successful operation event. Read the BPF LSM contract, event tracing interfaces and kprobe limitations.

Visibility is a measurable dependency

Capture sensor version, kernel release/build, architecture, loaded attachments, enabled events, namespace visibility, clock source, sampling configuration and loss counters. A healthy agent process does not prove that its required hooks are active. Establish canary operations and check that their expected events arrive.

Account for asynchronous I/O and kernel-worker attribution when testing your sensor. A syscall-only model is not automatically a complete model of file or network effects. Conversely, do not claim that io_uring is universally invisible: coverage depends on the operation, kernel and collector. User-space work may also occur without a new syscall. State the coverage you tested instead of guessing.

Identity tip. PID alone is unsafe because it can be reused. Preserve host ID, boot ID, process start identity, host PID/TID and namespace context. Add pod UID, container ID and image digest when available. An exec changes the process image without creating a new process; a fork creates a new identity. Preserve lineage explicitly.

03Read /proc/sys/kernel as a security control surface

The kernel sysctl reference describes controls, not a universal hardening profile. Verify availability and vendor behavior on the actual kernel. These concise semantics are the starting point:

  • unprivileged_bpf_disabled: 0 allows unprivileged BPF calls; 2 disables them reversibly; 1 cannot be cleared in the running kernel.
  • modules_disabled=1 prevents module loading and unloading; kexec_load_disabled=1 disables further kexec image loading. Both are one-way for the running kernel.
  • kptr_restrict constrains pointer disclosure through the documented formatting interfaces; dmesg_restrict limits kernel-log access. Neither is a universal information-leak fix.
  • core_pattern configures core handling; an initial pipe character selects a userspace handler.
  • io_uring_disabled restricts new ring creation; existing rings remain usable. Mode 1 permits the documented privileged/group exceptions; mode 2 blocks creation for everyone.
  • bpf_stats_enabled enables runtime statistics with overhead; it is not an incident recorder.

For perf restrictions, use the separate perf security model; capabilities and distribution-specific settings matter. For process inspection, Yama’s ptrace_scope distinguishes traditional checks, relationship-restricted attachment, admin-only attachment and a no-attach mode. This is additional policy, not a replacement for all process-access checks.

Turn configuration into an investigation contract

K8SEC’s proposed analytic is not “value differs from my laptop.” Maintain a versioned node baseline with approved exceptions. Join a change observation to the responsible process identity, authenticated operator or configuration-management job, expected value transition and maintenance window. A current value proves state at collection time; it does not identify who changed it. A failed write proves neither a changed value nor a later successful attempt.

Prioritize unexplained policy weakening or changes to execution-sensitive handlers. Review legitimate crash collectors, monitoring agents and driver maintenance before alerting. Do not paste a batch of irreversible settings into a worker. Establish required drivers and recovery procedures, test on a disposable node, then deploy through the supported node-management mechanism.

Read-only inventory · optional on an authorized Linux system
for key in kernel.unprivileged_bpf_disabled kernel.modules_disabled \
  kernel.kexec_load_disabled kernel.kptr_restrict kernel.dmesg_restrict \
  kernel.perf_event_paranoid kernel.yama.ptrace_scope kernel.io_uring_disabled
do
  if value=$(sysctl -n "$key" 2>/dev/null); then
    printf '%s=%s\n' "$key" "$value"
  else
    printf '%s=UNKNOWN (unavailable or not readable)\n' "$key"
  fi
done

This inventory makes no changes and does not establish collector coverage. A container’s view is not necessarily the host’s view. Record where it ran; keep inaccessible values UNKNOWN rather than treating them as disabled.

04Translate malware objectives into observable behavior

Reverse engineering starts with a hypothesis about a capability. Detection starts with what your telemetry can establish. An import, string or disassembled branch may reveal a possible operation without proving that execution reached it. Dynamic execution covers only the inputs, environment and branches exercised.

Behavior hypotheses, corroboration and legitimate lookalikes
HypothesisEvidence to seekAlternative explanation / limit
Anonymous-file-backed executionCreation of an anonymous file, correlated writes, then a successful execution transition resolving to that object. Track descriptor reuse and object lifetime.Legitimate launchers and IPC use anonymous files. Creation alone is not execution; an executable mapping is not proof that instructions ran.
Cross-process memory accessSource and target process identities, requested operation, returned byte count and independent authorization context.Debuggers and diagnostics read memory. A read is not an injection; it does not prove secrets were present or left the host.
Unexpected child processService lineage, successful image transition, executable provenance, credentials, namespace and workload expectations.A shell can be legitimate maintenance; an attacker need not invoke a shell. Names and command lines can mislead.
Credential access followed by outbound activityResolved sensitive object, successful access, same-subject or explicit IPC lineage, connection outcome and controlled evidence of content transfer.Temporal proximity alone does not prove that the file’s bytes were transmitted. A successful connect is not exfiltration.
Telemetry or policy tamperingUnauthorized configuration/attachment change, responsible identity, before/after state, sensor-health impact and an independent log source.Maintenance can detach probes or rotate agents. Lost events can also reflect pressure, crashes or misconfiguration.

memfd_create supplies anonymous file-backed storage, not a malware verdict. execve replaces the current program image; a successful exec does not return to the old program. Model successful execution using the collector’s completion/event semantics, not a fabricated universal “exec returned zero” record. process_vm_readv returns transferred bytes and can complete partially; ptrace has multiple operations whose meanings differ. Sources: memfd_create, execve, process_vm_readv, ptrace.

Attacker lens, defender discipline

An attacker seeks a useful effect: inspect another identity, reach a protected object or alter a policy. Your rule should describe that effect and its prerequisites, not a particular utility name. Start with the shortest defensible claim. “An unexpected process read bytes from another process” is stronger evidence than “malware injection detected” when all you have is a read result.

Do not automatically attach a technique, campaign or exploit chain to a syscall. Record the mapping rationale and leave unsupported claims unmapped. A successful host operation also does not establish a container escape: reconstruct the expected boundary, actual namespace/mount exposure and effective authority first.

05From reverse engineering to a detection specification

  1. Establish the specimen and scope. Record hashes, acquisition provenance, allowed environment and analyst ownership. Real malware belongs in a dedicated isolated analysis environment, not a production cluster or this website.
  2. Extract capability hypotheses. Describe relevant data flow, call sites and prerequisites. Mark static-only observations separately from exercised behavior. Identify inputs and branches that remain untested.
  3. Design controlled observations. Use disposable workloads, synthetic files and memory, bounded network simulation and independent outcome checks. Include an authorized positive baseline and a deliberately denied operation.
  4. Normalize semantics. Specify sensor-specific success/failure conventions, partial results, task identity and object resolution. Preserve raw event references; avoid flattening everything into “syscall happened.”
  5. Write the behavior contract. Declare the join keys, time window, required events, trust source for approval and missing-data behavior. Declare what the rule does not detect.
  6. Challenge the rule. Replay benign lookalikes, missing events, duplicates, reordered timestamps, reused PIDs and mismatched objects. Have another analyst reject any conclusion the evidence cannot support.
  7. Ship with observability. Version the rule, fixtures, sensor matrix and reviewer sign-off. Measure coverage and triage cost before enabling response automation.

A harmless trace to learn the recording format

In an authorized disposable Linux environment with strace, trace a fixed, benign shell command. It creates no payload and does not change kernel policy. The output file is created in your current directory. Loader and shell behavior will vary by system; that variation is part of the lesson.

Teaching capture · no malware · arguments may contain sensitive data
strace -f -ttt -yy -e trace=execve,openat,read,write,close \
  -o benign-trace.log -- /bin/sh -c 'printf "K8SEC benign fixture\n"'

Match a few entries to returns, resolve the visible file descriptors and explain the loader’s activity before writing a rule. -f follows child processes; timestamps and descriptor decoding help reconstruction, but do not magically provide immutable object identity. Tracing perturbs execution and can expose argument or buffer contents. See the strace manual. This article’s validation checks shell syntax; it does not execute this capture.

Expert tip: keep three artifacts. A static hypothesis, a dynamic observation and a detection decision should remain separate records. If a control blocks the tested path, preserve the attempted operation and the negative result. Do not rewrite the original hypothesis as a demonstrated compromise.

06Interactive evidence graph: one API, four investigations

Select a path and follow the directional relationships. Observed means supplied in this synthetic fixture, not measured on a real host. Inferred marks the analyst interpretation. Disproven applies only to the stated claim for this call. Approval is independent fixture context, not something a syscall authenticates.

Process → kernel result → analyst conclusion

Trust boundary: one process requests access to another process's memory. Decision boundary: kernel result is interpreted using independent authorization context.

All synthetic traces are readable below. This is not a live sensor.

Unexpected memory read

  1. Process boundary · observedSource → target memoryprocess_vm_readv request, invocation read-01. Compound process identities identify separate lifetimes.
  2. Result boundaryObserved · 64 bytes returnedEntry-to-exit correlation requires the same subject, target and call identity.
  3. Interpretation boundaryInferred · investigate scopeThe byte transfer is observed in this fixture. Whether the content was sensitive, maliciously used or transmitted elsewhere remains unproven.
Evaluation · synthetic records only
investigate-read: Unexpected cross-process byte transfer. This is not proof of injection or exfiltration.
Next evidence to obtain
Bind the subject to its workload and compare target scope against an independently managed entitlement.
Inspect normalized evidence and approval context
{
  "id": "unexpected",
  "label": "Unexpected memory read",
  "authorization": "unexpected",
  "coverage": "complete",
  "events": [
    {
      "phase": "enter",
      "at": 100,
      "call": "read-01",
      "subject": "nodeA/bootA/pid410/start90",
      "target": "nodeA/bootA/pid620/start70",
      "operation": "process_vm_readv"
    },
    {
      "phase": "exit",
      "at": 120,
      "call": "read-01",
      "subject": "nodeA/bootA/pid410/start90",
      "target": "nodeA/bootA/pid620/start70",
      "operation": "process_vm_readv",
      "result": 64
    }
  ]
}

Approved diagnostic

  1. Process boundary · observedSource → target memoryprocess_vm_readv request, invocation read-02. Compound process identities identify separate lifetimes.
  2. Result boundaryObserved · 64 bytes returnedEntry-to-exit correlation requires the same subject, target and call identity.
  3. Interpretation boundaryContext · approved diagnosticThe same low-level behavior has an approved purpose in this fixture. Approval is contextual evidence, not a syscall property or a global allowlist.
Evaluation · synthetic records only
approved-read: Bytes transferred under the fixture's independently supplied approval; retain the evidence.
Next evidence to obtain
Check the diagnostic's operator, target scope, executable provenance and expiry; retain the successful read record.
Inspect normalized evidence and approval context
{
  "id": "approved",
  "label": "Approved diagnostic",
  "authorization": "approved",
  "coverage": "complete",
  "events": [
    {
      "phase": "enter",
      "at": 100,
      "call": "read-02",
      "subject": "nodeA/bootA/pid411/start91",
      "target": "nodeA/bootA/pid620/start70",
      "operation": "process_vm_readv"
    },
    {
      "phase": "exit",
      "at": 120,
      "call": "read-02",
      "subject": "nodeA/bootA/pid411/start91",
      "target": "nodeA/bootA/pid620/start70",
      "operation": "process_vm_readv",
      "result": 64
    }
  ]
}

Denied attempt

  1. Process boundary · observedSource → target memoryprocess_vm_readv request, invocation read-03. Compound process identities identify separate lifetimes.
  2. Result boundaryObserved · -1 / EPERMEntry-to-exit correlation requires the same subject, target and call identity.
  3. Interpretation boundaryDisproven · bytes read by this callThe claim that this specific paired call transferred bytes is contradicted. Which policy denied it is unknown; another call or interface is outside this fixture.
Evaluation · synthetic records only
denied-attempt: The paired operation was denied; the responsible control is not identified.
Next evidence to obtain
Correlate relevant authorization records. Verify a controlled allowed baseline before concluding the policy is correct.
Inspect normalized evidence and approval context
{
  "id": "denied",
  "label": "Denied attempt",
  "authorization": "unexpected",
  "coverage": "complete",
  "events": [
    {
      "phase": "enter",
      "at": 100,
      "call": "read-03",
      "subject": "nodeA/bootA/pid412/start92",
      "target": "nodeA/bootA/pid620/start70",
      "operation": "process_vm_readv"
    },
    {
      "phase": "exit",
      "at": 120,
      "call": "read-03",
      "subject": "nodeA/bootA/pid412/start92",
      "target": "nodeA/bootA/pid620/start70",
      "operation": "process_vm_readv",
      "result": -1,
      "error": "EPERM"
    }
  ]
}

Missing return event

  1. Process boundary · observedSource → target memoryprocess_vm_readv request, invocation read-04. Compound process identities identify separate lifetimes.
  2. Result boundaryMissing · return eventEntry-to-exit correlation requires the same subject, target and call identity.
  3. Interpretation boundaryUnknown · outcome and authorityAn entry is recorded, but the return and complete telemetry are absent. Do not infer denial, success or a clean host.
Evaluation · synthetic records only
unknown: Missing records or collector coverage is incomplete.
Next evidence to obtain
Investigate sensor loss and recover independent evidence; the missing record cannot be manufactured by the graph.
Inspect normalized evidence and approval context
{
  "id": "incomplete",
  "label": "Missing return event",
  "authorization": "unknown",
  "coverage": "loss",
  "events": [
    {
      "phase": "enter",
      "at": 100,
      "call": "read-04",
      "subject": "nodeA/bootA/pid413/start93",
      "target": "nodeA/bootA/pid620/start70",
      "operation": "process_vm_readv"
    }
  ]
}

The graph deliberately keeps the same API across scenarios. Changing the outcome, approval or telemetry completeness changes the conclusion. No scenario yields a “malware confirmed” result. A denial does not prove which security control caused it, and absence of a return does not prove that nothing happened.

07A reproducible, deliberately narrow correlation rule

The downloadable model evaluates exactly one normalized process_vm_readv entry/exit pair. It requires matching call, subject and target identities, complete coverage, a finite ordered time interval of no more than five seconds, and an integer result. That window is a teaching parameter—not a production tuning recommendation.

A positive byte count plus independently supplied “unexpected” context produces investigate-read. An approved diagnostic produces approved-read, which retains the observation rather than calling the machine clean. A normalized -1/EPERM produces denied-attempt. Missing, conflicting or unsupported evidence remains unknown. Zero bytes produces no-bytes-observed, not “safe.”

Normalization warning: the fixture uses libc-style -1 plus symbolic errno. A kernel exit sensor may expose a negative errno directly. A production adapter must normalize and test that convention. The compound identity strings are readable stand-ins for collector-issued identities; this model cannot verify their authenticity, host clock, coverage assertion or approval authority.

Offline replay · Node.js · download both files into one directory first
node --input-type=module -e '
import {readFileSync} from "node:fs";
import {assess} from "./kernel-detection-v1.mjs";
const fixture = JSON.parse(readFileSync("./kernel-detection-fixtures-v1.json", "utf8"));
for (const trace of fixture.cases) console.log(trace.id, assess(trace));
'

Download reference evaluator v1 · JavaScript module · Download synthetic evidence v1 · JSON

What a production implementation still needs

This is not a kernel collector, malware classifier or SIEM integration. Build and test the trusted ingestion adapter, immutable process/object identities, event deduplication, bounded buffering, late-arrival policy and retention controls. If you support out-of-order events, distinguish reorderable arrival time from contradictory event time. Never join different boots or process lifetimes merely because a PID matches.

Replace the fixture’s approval label with an independently verified entitlement or bounded maintenance record. A process-controlled name, command line, environment variable or annotation cannot grant itself an exception. Bind exceptions to workload identity, operation, target scope and expiry. Treat incomplete instrumentation as degraded detection coverage and surface it separately from suspicious activity.

Detection versus response

Start in observation mode. A false positive on a node security agent can remove the very telemetry needed to investigate. Escalate with the raw event references and context, not an automatic kill based on one syscall. For enforcement, specify the supported control, compatibility tests, rollback and a separate proof that the deployed policy rejects the intended operation.

08eBPF is a programmable kernel surface—not a security verdict

eBPF allows approved programs to run at supported kernel hooks, with program-type-specific access to context, helpers and data. Networking, observability and security tools use it for different purposes. A userspace loader prepares an object, creates maps, asks the kernel to load programs, then attaches them. Successful loading alone does not prove attachment or useful events. libbpf lifecycle.

  1. 1 · Load requestThe loader’s credentials, kernel configuration and permissions constrain the requested program and attachment.
  2. 2 · VerifyThe verifier analyses register types, pointer bounds and valid accesses before acceptance; rejection is a load failure, not a detection event.
  3. 3 · Attach and runAccepted programs execute when their hook runs, through an interpreter or JIT-compiled code as supported. Hook type defines possible effects.
  4. 4 · Export and correlateMaps or event buffers carry state to a collector. Loss, sampling, restarts and identity enrichment determine evidence quality.

The verifier enforces rules about program safety; it does not decide whether your organization authorized the loader or whether a telemetry policy covers the attack path. Verifier/JIT implementation defects also remain part of the kernel patching threat model. Verifier design.

Maps hold state shared between BPF programs and, subject to access, userspace. Configuration maps deserve change control; changing one can alter a sensor’s behavior without a new program load. Pinning can keep referenced objects alive beyond a loader’s lifetime, so process exit is not a complete uninstall audit. BPF maps and object lifetime.

Permission review: loader, program and attachment

CAP_BPF separates privileged BPF operations on supporting kernels; tracing may also require CAP_PERFMON, and networking operations may require CAP_NET_ADMIN. Legacy checks can involve CAP_SYS_ADMIN. These are not a universal three-capability recipe: program type, attach target, user namespace, LSM and distro configuration affect the decision. An application does not need these merely because the node runs an eBPF-based CNI. Linux capabilities.

Maintain an owner, image digest, program type, attachment, required authority and approved data fields for every sensor. Prefer hashes/build identities over program names as identity evidence. Treat raw arguments, paths and process data as potentially sensitive; do not export secrets in pursuit of a richer dashboard.

Inventory is not a completeness proof. On an authorized host with matching tooling, bpftool prog show, bpftool link show and bpftool map show help enumerate objects. Attachments are not all represented by modern BPF links; inspect network/cgroup hooks through the supported toolchain too. Permission denial means UNKNOWN, not “no eBPF”. Do not dump map contents or disable a CNI/security agent to make the inventory easier. bpftool inventory reference.

09What a container escape actually changes

A container escape is an action that crosses the workload’s intended isolation boundary into host resources or authority it should not possess. The phrase describes the result, not one particular exploit. Access to a host directory intentionally mounted into a pod may be a dangerous grant rather than a bypass; record the intended policy before calling it an escape.

There are at least three different mechanisms: an over-granted interface, a vulnerable userspace runtime, and a vulnerable kernel. They require different fixes. MITRE T1611, Escape to Host, is an investigation category—not proof that a weak configuration has already been exploited.

Interactive escape-path comparison

Choose a path to compare its boundary, controls and evidence. This is an explanatory model, not a live cluster test.

All paths shown. No JavaScript is required to read them.

Path A · dangerous grant, no kernel bug required

  1. ApplicationCompromised workloadStarts with its actual process credentials and mounts.
  2. Grant boundaryWritable host path / runtime interfaceRequires an exposed interface and sufficient effective access.
  3. Host userspaceUnauthorized host effectThe kernel may simply be honoring an over-broad grant.
Authority / control
Prerequisites: reachable sensitive interface, effective permissions and no other control blocking the operation.
Observation
Evidence: admitted configuration, mount/object identity, process authority and an independently recorded benign host effect in an isolated test.
Effect / remediation
Interrupt: remove the grant and restrict admission. A kernel patch alone does not remove a writable host mount.

Path B · container runtime isolation failure

  1. Application / imageAttacker-controlled runtime inputReachable start, exec or filesystem operation; depends on the specific flaw.
  2. Runtime boundaryAffected userspace runtimeA concrete defect mishandles isolation, a path or a descriptor.
  3. Host userspaceAccess outside intended isolationHost impact is conditional; the kernel itself need not be corrupted.
Authority / control
Prerequisites: affected runtime build, exact triggering conditions and reachable runtime operation.
Observation
Evidence: vendor advisory match, runtime version, safe isolated reproduction and host-object result. Do not infer exposure from a kernel version.
Effect / remediation
Interrupt: update the affected runtime through the supported platform release and remove unnecessary triggering authority.

Path C · a reachable kernel defect

  1. ApplicationProcess reaches a vulnerable interfaceThe relevant syscall/device/protocol must be permitted and available.
  2. Kernel integrityAffected kernel path and exploit primitiveSuccessful exploitation may alter privileged state; a crash alone is not proof.
  3. Node / neighborsPotential shared-host impactConfidentiality, integrity or availability depends on the demonstrated primitive.
Authority / control
Prerequisites: affected vendor build, reachable interface and the exploit’s exact configuration/privilege requirements.
Observation
Evidence: payload/advisory mapping and authorized isolated validation; separate failed attempts, crashes and controlled impact.
Effect / remediation
Interrupt: patch the node kernel and reduce reachability. Additional cluster access still requires credentials, permissions and network paths.

How does escape impact the kernel?

Host userspace control

A host file or runtime socket can expose node authority while the kernel executes its configured rules correctly. The primary failure can be the permission grant, not kernel memory corruption.

Kernel confidentiality / integrity

A reachable kernel defect may disclose memory or permit a privileged state change. Its exact primitive and prerequisites determine impact; a crash is not proof of code execution.

Shared-node availability

A kernel panic can interrupt other workloads on that worker. Resource exhaustion may also affect neighbors without an escape. Keep denial of service separate from demonstrated host control.

Conditional cluster reach

Host access may expose workload or node credentials. Further access still depends on credential scope, RBAC, network reachability and additional controls. Node compromise is not automatically cluster-admin.

Root inside a container, visibility of host PIDs, an allowed syscall, and successful host access are four different observations. Report the narrowest supported claim. A service-account token used against the Kubernetes API can produce a serious cluster attack path without any kernel escape at all.

Recovery follows the breached boundary. Rebuilding a compromised image does not repair a node kernel. Patching a kernel does not revoke a stolen credential. If host integrity is lost, preserve evidence, contain according to the incident runbook, rotate exposed authority and reprovision through the supported node lifecycle before restoring trust.

10Collect effective state before assigning severity

Start with API metadata. Preserve node and pod UIDs, container identity, release, timestamps and collection errors. The following triage includes regular, init and ephemeral containers; it deliberately does not fetch Secret objects or values.

bash# Authorized read-only API inventory; jq 1.6+.
oc get clusterversion -o jsonpath='{.items[0].status.desired.version}{"\n"}'
oc get mcp
oc get co
oc get pods -A -o json | jq -c '
  .items[] as $p
  | (($p.spec.containers // []) + ($p.spec.initContainers // [])
    + ($p.spec.ephemeralContainers // []))[] as $c
  | select(
      $c.securityContext.privileged == true
      or $p.spec.hostPID == true or $p.spec.hostIPC == true
      or $p.spec.hostNetwork == true
      or any($p.spec.volumes[]?; has("hostPath"))
      or any($c.securityContext.capabilities.add[]?;
        . == "SYS_ADMIN" or . == "SYS_PTRACE" or . == "SYS_MODULE"
        or . == "BPF" or . == "PERFMON" or . == "NET_ADMIN"))
  | {namespace:$p.metadata.namespace, pod:$p.metadata.name,
     podUID:$p.metadata.uid, node:$p.spec.nodeName,
     serviceAccount:($p.spec.serviceAccountName // "default"),
     scc:($p.metadata.annotations["openshift.io/scc"] // "UNKNOWN"),
     container:$c.name, securityContext:$c.securityContext}'

This flags candidate paths, not vulnerabilities. Inspect volume mounts, device exposure, runtime defaults and the actual process credentials next. For SCC entitlement, combine RBAC grants with the SCC’s own users/groups; a single oc auth can-i result is not a complete SCC grant inventory. Red Hat SCC reference.

Host inspection has a different authorization boundary

oc debug node is not a read-only Kubernetes operation: it creates a privileged debugging workload. chroot /host changes the filesystem view; it does not manufacture safe access. Use an approved administrator session and an explicitly selected canary node. Do not grant host-debug privilege to ordinary application accounts or to the production K8SEC Agent.

Within an already approved host inspection session, the following script reads metadata. Missing files and denied reads remain UNKNOWN. It does not prove every control is enforced or capture a trusted forensic image.

bash#!/bin/sh
# Run in an already authorized host inspection session, not inside an app pod.
# Prints metadata only. Does not change sysctls, load BPF or read Secret values.
show_file() {
  printf '\nFILE %s\n' "$1"
  if [ -r "$1" ]; then
    cat "$1" || printf 'UNKNOWN: read failed\n'
  else
    printf 'UNKNOWN: unavailable or not readable\n'
  fi
}
date -u '+UTC %Y-%m-%dT%H:%M:%SZ'
hostname
uname -r
show_file /proc/sys/kernel/random/boot_id
show_file /proc/cmdline
show_file /sys/fs/selinux/enforce
show_file /sys/kernel/security/lsm
show_file /sys/kernel/security/lockdown
for key in kernel.yama.ptrace_scope kernel.unprivileged_bpf_disabled \
  kernel.perf_event_paranoid kernel.kptr_restrict kernel.dmesg_restrict \
  kernel.randomize_va_space fs.suid_dumpable; do
  printf '\nSYSCTL %s\n' "$key"
  sysctl "$key" || printf 'UNKNOWN: sysctl failed\n'
done
for f in /sys/devices/system/cpu/vulnerabilities/*; do
  [ -e "$f" ] || continue
  show_file "$f"
done

Download the read-only host snapshot script (SH · v1). Review before use; this article does not claim it has been run on your OpenShift workers.

Interpretation guardrails
EvidenceSupported interpretationDo not infer
SELinux enforce = 1Live SELinux enforcement at collection time; inspect process labels and policy too.All workload actions are denied or every container is correctly labeled.
Seccomp = 2 in process statusA filter is installed for that process.The exact allowed syscall set or effective policy version.
ptrace_scope = 0Traditional access checks still apply, including identity/dumpability.Any pod can inspect every host process.
randomize_va_space = 2Userspace ASLR setting.Kernel ASLR, signed boot, PIE or stack canaries are proven.
No BPF module in lsmodNo useful BPF availability conclusion.Built-in eBPF support is absent.
A kernel release stringOne input to payload and vendor advisory matching.Whether the distro has backported a particular fix.

For ptrace restrictions, use the Yama semantics. For kernel knobs, use the sysctl reference, and map the actual OpenShift/RHCOS payload to vendor advisories instead of comparing upstream version strings alone.

11Break the path without breaking the cluster

Choose controls for the transition they constrain. Admission governs requested privileges; runtime policy governs execution; patching removes known defects. A sensor can support all three with evidence, but it does not substitute for any of them.

Control-to-boundary review
BoundaryControl to validateResidual question
Pod → host featuresConstrained SCC, no unapproved privileged/host namespaces/hostPath, drop capabilities.Who can grant exceptions or change the workload?
Process → kernel APIRuntimeDefault seccomp and workload-tested tighter profiles where needed.What does the actual runtime profile allow?
Subject → objectEnforcing SELinux and correct labels/MCS separation.Did policy deny the controlled cross-label test?
Loader → kernel instrumentationApproved BPF loaders, minimal required privilege, unprivileged BPF restrictions.Can an unauthorized workload load or attach the relevant program type?
Node → trusted executionSupported payload updates, measured boot controls and supported lockdown/module-signing policy.What is the evidence for this node, rather than its template?

restricted-v2 drops capabilities and applies runtime-default seccomp; newer SCC options and user namespaces depend on release/configuration. Inspect the admitted pod rather than assuming a default. Avoid blanket changes to built-in SCCs. SCC behavior.

A scoped TuneD example—not a universal baseline

Evaluate host sysctls through the Node Tuning Operator. This example inherits openshift-node and matches one explicit label; lower priority numbers win. Adapt inheritance and conflicts to your pool, especially performance-tuned nodes. NTO profile matching.

yamlapiVersion: tuned.openshift.io/v1
kind: Tuned
metadata:
  name: k8sec-kernel-canary
  namespace: openshift-cluster-node-tuning-operator
spec:
  profile:
    - name: k8sec-kernel-canary
      data: |
        [main]
        summary=K8SEC single-worker evaluation
        include=openshift-node
        [sysctl]
        kernel.yama.ptrace_scope=1
        kernel.unprivileged_bpf_disabled=2
        kernel.perf_event_paranoid=2
        kernel.kptr_restrict=1
        kernel.dmesg_restrict=1
        fs.suid_dumpable=0
  recommend:
    - match:
        - label: k8sec.io/kernel-canary
          value: "true"
          type: node
      priority: 10
      profile: k8sec-kernel-canary

unprivileged_bpf_disabled=2 disables unprivileged BPF reversibly on supporting kernels; 1 cannot be reversed until reboot. Neither revokes all privileged BPF access. Check existing values first. kptr_restrict and dmesg_restrict reduce information exposure, not exploitability to zero. Kernel knob semantics. Profiling restrictions need separate evaluation for legitimate agents and CAP_PERFMON: perf security.

  1. Baseline: choose a replaceable worker; record its active TuneD profile, original values, BPF consumers, operator health and application SLOs.
  2. Review: server-side dry-run the manifest, check inherited settings and ensure only the intended node bears the canary label.
  3. Change: apply only in the approved window. Confirm selected profile, live values and positive/negative control results—not just an accepted YAML object.
  4. Compatibility: exercise CNI, CSI, APM, security sensors, profiling, crash collection and workload probes before widening scope.
  5. Rollback: remove the canary match and restore the recorded prior profile/values through the supported operator process. Verify every value. Removing a label alone is not proof that all sysctls reverted.

Kernel arguments and RHCOS lifecycle changes need separate Machine Config Operator planning, disruption budgets and maintenance windows. MachineConfig guidance. An SELinux-disabled boot is not repaired by setenforce 1; inspect the configuration source and plan supported recovery. Do not turn broad audit2allow output into an unreviewed exception.

Detection engineering feedback loop: a rule is an evolving claim, not a verdict machine
  1. HypothesisState attacker objective, expected behavior, valid alternative and required outcome.
  2. Coverage contractRecord hook, policy version, supported nodes, loss, event-time identity and safe canary.
  3. Raw evidenceKeep the syscall/LSM/Tetragon event, return value, lineage and Kubernetes audit separately.
  4. Correlation gateDeduplicate, time-bound, join on stable IDs; ambiguous or missing edges stay unknown.
  5. AdjudicationConfirmed effect, denied attempt, benign control or unresolved candidate—with reasons.
Analyst review → tune the hypothesis and exception scope → replay positive and negative controls. Never auto-delete on a suspicion score.

12Operate the detector, not just the rule

A detection is a maintained system: sensor, parser, identity mapping, correlation, enrichment, alert route and reviewer. Measure each part. A rule that never alerts because its event vanished after a kernel update is broken, not precise.

  • Coverage: maintain a kernel/architecture/runtime/sensor matrix. Replay the expected allowed and denied canaries after upgrades. Record unsupported configurations.
  • Evidence quality: track lost records, queue latency, attachment failures, unresolved identities and clock discontinuities. Keep UNKNOWN visible instead of counting it as a passed negative control.
  • Evaluation: report precision on labeled reviewed alerts, and recall on your explicitly bounded test corpus—not all malware. Also measure false positives per workload-hour, investigation time and repeated alerts per incident.
  • Privacy: default to metadata. Arguments, paths, environment and buffers may expose credentials or tenant data. Minimize collection, restrict access, redact deliberately and document the evidence lost through redaction.
  • Cluster correlation: join runtime subject identity to pod UID, container ID, image digest, node and Kubernetes audit records. The ServiceAccount is not the Linux UID, and Kubernetes RBAC does not explain every kernel decision.
  • Resilience: forward evidence off-node under controlled access. A compromised kernel can undermine host telemetry; a clean local event stream is not proof of kernel integrity.
Intent → operation → identity → result → justified conclusion
1 · Name the mechanism

ABI syscall, internal function, tracepoint or LSM hook? Separate sysfs object paths from sysctl settings.

2 · Prove sensor coverage

Build, configuration, attachments, canary events, loss counters and namespace visibility.

3 · Join the right objects

Host and boot, process birth identity, invocation, target identity and bounded time. PID is not enough.

4 · Test alternatives

Approved diagnostic, denied attempt, missing result and contradictory evidence. Retain uncertainty.

5 · Separate effect from intent

Bytes read are not injection, connection is not exfiltration, and a policy request is not a successful change.

6 · Maintain the contract

Versioned fixtures, review, exceptions with expiry, privacy, upgrade tests and response rollback.

Operator cheat sheet

Request only: attempted operation. Failure: rejected or failed call, cause needs attribution. Successful bytes: transfer for this call, not content classification. Approval: independent contextual record. Missing telemetry: unknown. Same PID: insufficient identity. Same time window: insufficient causality.

This checklist is a reading aid, not an automated security score. Ticks reset when the page reloads.

0 controls verified

Source and validation boundary

Mechanism references are linked alongside the relevant claims; reviewed October 17, 2026. The correlation contract and investigation guidance are K8SEC’s analysis. Automated tests validate synthetic logic, page behavior and links; they do not validate a live kernel sensor or establish real-world malware detection rates.

Continue with Kubernetes audit-log investigations and kernel boundaries and OpenShift hardening. K8SEC Agent remains read-only Kubernetes graph intelligence: no Secret-value collection, pod exec, resource mutation or autonomous exploitation.

I want an alert that can survive a skeptical investigation: the exact subject, the exact operation, the result, the policy context and the evidence we could not collect. A frightening syscall name is not enough.

The goal is not more kernel events. It is fewer unsupported conclusions.

Riad DAHMANI — K8SEC Security Research

Follow the evidence across boundaries.

Explore the documented relationships behind K8SEC research. A graph relationship is a hypothesis or a sourced statement—not automatic proof of compromise.

Explore K8Map research
On this pageTetragon kernel-operation lifecycleLayered Linux kernelSpeak precisely about the boundaryChoose sensors by the question they can answerRead /proc/sys/kernel as a security control surfaceTranslate malware objectives into observable behaviorFrom reverse engineering to a detection specificationInteractive evidence graph: one API, four investigationsA reproducible, deliberately narrow correlation ruleeBPF program lifecycleEscape path comparisonEffective state and host evidenceOpenShift hardeningDetection feedback loopOperate the detector, not just the rule