Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
bpfjailer — eBPF LSM based Mandatory Access Control and jailer | Kitploit
Tools/GitHubGitHub/facebookincubator/bpfjailer
Authentication & AuthorizationDefensive ToolsPrivilege EscalationContainer SecurityConfiguration AuditingNetwork Access Control
GitHubfacebookincubator/bpfjailer

bpfjailer

eBPF LSM based Mandatory Access Control and jailer

View Repository
36291 day agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

BpfJailer

eBPF based Mandatory Access Control for Linux.

This project is a full rewrite of the closed source BpfJailer and is completely experimental. It leverages newer features like bpf arena that were not available when the internal BpfJailer was written. Issues are expected and are not eligible for bug bounty or considered security findings. Once properly evaluated it will replace the internal closed source version.

BpfJailer uses eBPF LSM programs to put processes into jails, called pods, each bound to a role from a TOML policy. A pod is inherited across fork and exec. Optional policy features:

  • Signed binaries — binaries executed must enable fs-verity and a signature from a named set of certificates.
  • kill and ptrace — target roles/pods this may signal or attach to.
  • bpf — which roles' eBPF maps and programs a role may open, or whether it may call bpf(2) at all.
  • keyring — which roles' fs-verity keyrings a role may add certificates to, or whether it may write keyrings at all.
  • Filesystem paths — read and write access to filesystem paths.
  • Executable code — what paths can be execed or used as dlls.
  • Kernel loading — kernel module and kexec loading.
  • IPC — ownership-aware System V and POSIX message queues and shared memory, and variable-expanded name patterns for POSIX objects.
  • Unix sockets — pathname and abstract-name policy for bind, connect and datagram destinations.
  • Mounts — destination and filesystem-type rules.

Denials and lifecycle events are written to pinned ring buffers. bpfjlog prints the human-readable BPF diagnostics and structured events and follows the ring buffers across a live policy replacement.

A binary can claim a role through the user.bpfj.policy.exec xattr and is enrolled in it at exec time. Running processes can also be enrolled directly, and an unprivileged process can enroll itself through bpfjsrv/bpfjclient.

Components

DirectoryBinaryPurpose
bpfj/The core library and BPF programs: jailer, enforcers, policy parser, libbpf C++ helpers.
ctl/bpfjctlGeneral purpose tool for attaching, reloading, inspecting and detaching the jailer, and for enrolling processes.
cmd/bpfjcmdbpfjctl with its arguments, and optionally its policy, compiled in. It ignores argv, so it can be statically linked and fs-verity signed as a single unit.
srv/bpfjsrvSocket activated server that enrolls unprivileged callers into roles that allow it.
client/bpfjclientMinimal client for bpfjsrv, with no libbpf or BPF-toolchain dependency.
log/bpfjlogConsumer for the pinned diagnostic and structured-event ring buffers.
tests/bpfjtestTest suite.

Requirements

  • Linux 6.16 or newer with BPF LSM enabled (CONFIG_BPF_LSM=y and bpf in the lsm= boot parameter). BpfJailer is only tested on 6.16+, and older kernels are not supported.
  • clang (for BPF codegen), bpftool, and a C++20 compiler.
  • libbpf
  • A checkout of libarena, which provides the arena spin lock the BPF programs use.
  • For signed builds: openssl, fsverity and setfattr, plus the static archives listed in the Makefile (STATIC=1).

Set LIBBPF_CFLAGS / LIBBPF_LIBS if pkg-config cannot find libbpf. Point LIBARENA at the libarena checkout on every build:

Building

Every make below also needs LIBARENA (see Requirements), set on the command line or exported in the environment.

make                # build/bpfjctl
make STATIC=1       # bpfjctl with no shared object dependencies
make client         # build/bpfjclient, no BPF toolchain needed
make log            # build/bpfjlog
make signing-key    # generate a development signing key and certificate
make signed SIGNING_KEY=... SIGNING_CERT=...   # static, fs-verity signed bpfjctl
make srv  SIGNING_KEY=... SIGNING_CERT=...     # static, signed bpfjsrv
make cmd  SIGNING_KEY=... SIGNING_CERT=... \
     CMD_ARGS="replace-compiled" CMD_POLICY=policy.toml CMD_ROLE=bpfjailer
make clean

All output goes under build/. Set BUILD= to build somewhere else, for example make BUILD=build-asan SANITIZE=address,undefined.

Testing

make test

The tests have to run as root, because each one creates a mount namespace and mounts a bpffs. make test builds as the invoking user and runs only the test binary under sudo.

Tests run serially by default because concurrent BPF LSM detach can panic affected kernels. Use make test TEST_ARGS=Suite.Test for a focused case, and only opt into -j N or BPFJTEST_JOBS=N inside a disposable VM.

Usage

sudo bpfjctl check  policy.toml          # parse a policy and report what it holds
sudo bpfjctl attach policy.toml          # load and pin the jailer
sudo bpfjctl replace policy.toml         # reload without releasing jailed tasks
sudo bpfjctl wrap ROLE USER_ID -- CMD    # run CMD in a new pod
sudo bpfjctl enroll ROLE USER_ID PID [NAME=VALUE...] # enroll with variables
sudo bpfjctl show PID                    # pods a process is in
sudo bpfjctl list                        # every pod and its processes
sudo bpfjctl detach                      # unpin and unload

The programs are pinned under /sys/fs/bpf/bpfj-pins by default. Use --bpffs-path and --pin-dir to change this. They stay loaded until detach runs.

bpfjctl wrap without --drop-cap and a non-root --uid leaves the command able to remove itself from the jail. See bpfjctl wrap --help.

Run sudo build/bpfjlog while the jailer is attached to observe it. BPF diagnostics are written to stderr and structured events to stdout. The logger automatically reconnects when replace swaps in a new set of pinned maps.

replace loads a complete second jailer beside the active one, migrates pod membership, variables and tracked resource ownership, then atomically swaps the pin trees. Both trees remain attached during the handoff, forks and enrollment are coordinated with the migration, and ownership changes are journaled and replayed. Replacement fails closed if persisted layout versions are incompatible or the state cannot be copied safely.

Policy

base-role = "floor"           # optional: enroll every process on the host
vars = ["vm_uuid"]            # known variable names

[certs]
corp-ca = "MIIDXTCCAkWgAwIBAgIJAK..." # PEM or base64 DER certificate

[roles.floor]
any = true                    # open tracking-only base role

[roles.webserver]
enforce-binary-certs = ["corp-ca"] # execs must be signed by one of these
kill-roles = ["floor"]        # may signal its own pod, plus these roles
ptrace-pod = true             # its own pod only
proc-roles = ["floor"]        # may open proc files for these roles
bpf-pod = true                # only BPF objects from its own pod
lkm-any = false               # deny module and kexec loading
mq-sysv-pod = true            # only SysV queues from its own pod
mq-posix-pod = true           # only POSIX queues from its own pod
shm-sysv-pod = true           # only SysV SHM from its own pod
shm-posix-pod = true          # only POSIX SHM from its own pod
keyring-own = true            # only its own role's keyring

[[roles.webserver.mq-posix-pattern]]
name = "/service-${vm_uuid}-*"
allow = true

[[roles.webserver.shm-posix-pattern]]
name = "/service-${vm_uuid}-*"
allow = true

[[roles.webserver.exec-paths]]
path = "/usr/bin/webserver"
allow = true
permissions = ["exec"]

[[roles.webserver.exec-paths]]
path = "/usr/lib"
allow = true
permissions = ["shared-object"]

[[roles.webserver.paths]]     # cached path policy
path = "/"
allow = false

[[roles.webserver.paths]]
path = "/usr"
allow = true
access = "read-only"

[[roles.webserver.paths]]
path = "/etc"
allow = true
access = "read-only"
Download Tool