LSM BPF: Enforcing Security Right Inside...
SecurityLinux

LSM BPF: Enforcing Security Right Inside the Kernel

So far our eBPF has only observed. LSM BPF enforces: it attaches to the kernel's security hooks (Linux Security Modules) that SELinux and AppArmor use, and a program returns 0 to allow or -EPERM to block. This article writes an LSM program that blocks opening a file, and hits a lesson: it loaded and attached but blocked nothing — because bpf wasn't an active LSM. After enabling bpf via a boot parameter and rebooting, it blocks for real — both cat and python get Operation not permitted.

K
KaiMay 24, 2026· 22 views
The Verifier: Why eBPF Doesn't Crash the...
SecurityLinux

The Verifier: Why eBPF Doesn't Crash the Kernel

Article 1 said the eBPF virtual machine design lets the verifier prove safety. This article watches it for real: we compile an XDP program that reads the first byte of a packet but forgets the bounds check, load it — the verifier rejects it with a log naming the exact register and reason. Add one data_end check and it goes through. The verifier is a safety prover at load time, tracking each register's state across every branch — letting eBPF load foreign code into the kernel safely.

K
KaiMay 24, 2026· 17 views
eBPF From Scratch: Running Programs Insi...
NetworkingLinux

eBPF From Scratch: Running Programs Inside the Linux Kernel

Right now, on a worker of the Kubernetes cluster we built in the previous series, 140 eBPF programs are running inside the Linux kernel — routing every packet, controlling device access, collecting metrics. eBPF lets you load code into the kernel and run it safely at hooks, without changing kernel source and without loading a module. This opening article explains what eBPF is, why it changes how the kernel is extended, and how a program goes from code to native machine code.

K
KaiMay 24, 2026· 29 views
BTF and CO-RE: Compile Once, Run on Ever...
LinuxeBPF

BTF and CO-RE: Compile Once, Run on Every Kernel

Kernel data structures like task_struct have different layouts across kernel versions — a field sits at a different offset per build. So how does a pre-compiled eBPF program read the right field on every kernel? BTF and CO-RE. This final Part I post generates vmlinux.h from the kernel's BTF, writes a program that reads ppid by walking task->real_parent->tgid, compiles once and runs — libbpf finds the right offset from the running kernel's BTF. The foundation for Part III.

K
KaiMay 24, 2026· 19 views
Program Types and Hooks: Where You Attac...
LinuxeBPF

Program Types and Hooks: Where You Attach, What You See

An eBPF program doesn't run in a vacuum — it attaches to a hook in the kernel, and the kind of hook decides three things: when the program runs, what context it receives, and which helpers it may call. This post lists the program types the kernel supports, then attaches a tracepoint to the openat syscall to watch it run for real on every file open — contrasted with the XDP packet receiver from the previous post, to show why two programs that are both eBPF each see a completely different world.

K
KaiMay 24, 2026· 18 views
Maps: Memory and the Bridge to Userspace
LinuxeBPF

Maps: Memory and the Bridge to Userspace

An eBPF program runs per event then shuts off, keeping no variables between runs. Maps are how it remembers state and talks to userspace. This article writes a program that counts every process exec into a map, loads it into the kernel, runs a few commands, then reads the map from userspace with bpftool — watching the number actually go up. Plus inspecting a real Cilium map holding per-CPU metrics, and distinguishing a plain array from a per-CPU one.

K
KaiMay 24, 2026· 14 views
The eBPF Virtual Machine: Registers, Ins...
LinuxeBPF

The eBPF Virtual Machine: Registers, Instruction Set, and Bytecode

Last article we saw an eBPF program with 'xlated 512B' (verified bytecode) and 'jited 333B' (machine code). This article goes inside that bytecode: eBPF is a RISC-style virtual machine with 11 64-bit registers and a small instruction set, designed to translate quickly to native code and be verifiable for safety. We read a running Cilium program's bytecode directly, see how each instruction maps to registers and its class, then why this design lets the verifier prove safety.

K
KaiMay 24, 2026· 17 views