Skip to content

leodido/kfeatures

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

97 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kfeatures

Go Reference CI Latest release Go version License

Can my eBPF tool actually run here, and if not, exactly what needs to change?

kfeatures is a pure-Go library that answers this question.

It probes kernel capabilities at runtime and returns actionable diagnostics: not just unsupported, but why and how to fix it.

if err := kfeatures.Check(kfeatures.FeatureBPFLSM, kfeatures.FeatureBTF); err != nil {
    var fe *kfeatures.FeatureError
    if errors.As(err, &fe) {
        log.Fatalf("%s — %s", fe.Feature, fe.Reason)
        // Output: BPF LSM — CONFIG_BPF_LSM=y but 'bpf' not in active LSM list; add lsm=...,bpf to kernel boot params
    }
}

Why not cilium/ebpf/features or bpftool?

cilium/ebpf/features answers: "Does this kernel support program type X?"

bpftool feature probe answers: "What BPF features does this kernel have?" (CLI only, not embeddable in Go)

Neither tells you whether your tool can actually run. For example, BPF LSM requires three things simultaneously: CONFIG_BPF_LSM=y in the kernel config, bpf in the active LSM boot parameter list, and the LSM program type supported by the running kernel. cilium/ebpf/features can only check the last one. bpftool can check the first and last, but not the second. Neither provides remediation guidance.

Capability cilium/ebpf/features bpftool feature probe kfeatures
BPF program type probes
BPF map type / helper probes ✓ †
BTF availability (/sys/kernel/btf/vmlinux) ✗ *
Kernel config parsing (any CONFIG_*, =y/=m)
Active LSM list (/sys/kernel/security/lsm)
BPF LSM enabled (config + boot params + program type)
IMA detection (LSM list + securityfs directory)
IMA active measurement (runtime policy detection)
Process capabilities (CAP_BPF, CAP_SYS_ADMIN, CAP_PERFMON)
Unprivileged BPF status
Mount-state gates (bpffs/tracefs/custom paths via superblock magic)
ELF requirement extraction (parse .o, derive requirements)
Composite feature validation
Actionable diagnostics (remediation steps)
Selective probing (minimize overhead) ✓ ‡ ✗ §
Pure Go, no CGO
Usable as a Go library

* bpftool checks CONFIG_DEBUG_INFO_BTF in the kernel config but does not verify /sys/kernel/btf/vmlinux exists. † Exposed in kfeatures as parameterized requirements (RequireMapType, RequireProgramHelper) consumed by Check(...). cilium/ebpf/features is per-function: callers invoke individual probe functions on demand. § bpftool feature probe runs the full probe set on every invocation.

Other Go projects (libbpfgo, Tetragon, Falco libs) have some feature detection built in, but none is a standalone reusable library. They are either CGO-dependent, tightly coupled to their parent project, or written in C/C++.

Installation

go get github.com/leodido/kfeatures

Usage

Quick check

Validate that required kernel features are available:

import (
    "errors"
    "log"

    "github.com/leodido/kfeatures"
)

if err := kfeatures.Check(kfeatures.FeatureBPFLSM, kfeatures.FeatureBTF); err != nil {
    var fe *kfeatures.FeatureError
    if errors.As(err, &fe) {
        log.Fatalf("kernel not ready: %s — %s", fe.Feature, fe.Reason)
    }
}

Mixed requirements

Combine Feature enums with parameterized workload requirements:

import (
    "github.com/cilium/ebpf"
    "github.com/cilium/ebpf/asm"
    "github.com/leodido/kfeatures"
)

err := kfeatures.Check(
    kfeatures.FeatureBTF,
    kfeatures.RequireProgramType(ebpf.XDP),
    kfeatures.RequireMapType(ebpf.Hash),
    kfeatures.RequireProgramHelper(ebpf.XDP, asm.FnMapLookupElem),
)

Custom mount paths (RequireMount)

Gate on a filesystem mounted at an arbitrary path with the expected superblock magic — useful when bpffs lives somewhere other than /sys/fs/bpf:

import (
    "github.com/leodido/kfeatures"
    "golang.org/x/sys/unix"
)

err := kfeatures.Check(
    kfeatures.RequireMount("/run/bpf", unix.BPF_FS_MAGIC),
)

Magic constants come from golang.org/x/sys/unix (e.g. unix.BPF_FS_MAGIC, unix.TRACEFS_MAGIC, unix.CGROUP2_SUPER_MAGIC).

Reusable presets (FeatureGroup)

FeatureGroup packages a set of requirements as a single value you can pass anywhere a Requirement is accepted:

var TracingTool = kfeatures.FeatureGroup{
    kfeatures.FeatureBTF,
    kfeatures.FeatureKprobeMulti,
    kfeatures.RequireProgramType(ebpf.Kprobe),
}

if err := kfeatures.Check(TracingTool); err != nil {
    log.Fatal(err)
}

Extract requirements from a compiled object (FromELF)

Point FromELF at an eBPF .o and get back a FeatureGroup describing its program types, map types, and helper-per-program requirements — directly consumable by Check:

reqs, err := kfeatures.FromELF("./bpf/probe.o")
if err != nil {
    log.Fatal(err)
}
if err := kfeatures.Check(reqs); err != nil {
    log.Fatalf("kernel cannot run probe.o: %v", err)
}

Output is deterministic (deduplicated, stably ordered). Unknown ELF kinds fail closed.

Render remediation (Diagnose)

Check returns the diagnosis for the first failing feature. To inspect any feature against a single probe snapshot, call Diagnose directly:

sf, _ := kfeatures.Probe()
if !sf.BPFLSMEnabled.Supported {
    fmt.Println(sf.Diagnose(kfeatures.FeatureBPFLSM))
    // CONFIG_BPF_LSM=y but 'bpf' not in active LSM list; add lsm=...,bpf to kernel boot params
}

Full probe

Probe all features for diagnostics and reporting:

sf, err := kfeatures.Probe()
if err != nil {
    log.Fatal(err)
}
fmt.Println(sf)

Sample output (truncated):

Kernel: 6.1.0-generic

Program Types:
  LSM: yes
  kprobe: yes
  kprobe.multi: yes

Core:
  BTF: yes

Security Subsystems:
  BPF LSM enabled: yes
  IMA enabled: no
  IMA directory: yes
  Active LSMs: lockdown, capability, yama, apparmor, bpf

Filesystems:
  tracefs: yes
  bpffs: yes

Individual fields are typed and inspectable programmatically — see SystemFeatures.

Selective probing

Probe only what you need:

sf, err := kfeatures.ProbeWith(
    kfeatures.WithProgramTypes(ebpf.LSM, ebpf.Kprobe),
    kfeatures.WithSecuritySubsystems(),
    kfeatures.WithCapabilities(),
)

WithX options select probe scope. They do not define requirements — use Check(...) for gating.

CLI

A CLI is included for operator diagnostics and CI/CD gating:

go install github.com/leodido/kfeatures/cmd/kfeatures@latest
kfeatures probe                                    # probe all features
kfeatures check --require bpf-lsm,btf,cap-bpf      # exit 0 if met, 1 otherwise
kfeatures probe --json                             # JSON output
kfeatures config                                   # display kernel config

What it detects

Category Features
Program types LSM, kprobe, kprobe.multi, tracepoint, fentry
Core BTF availability (CO-RE)
Security BPF LSM enabled, IMA enabled, IMA active measurement, active LSM list
Capabilities and runtime gates CAP_BPF, CAP_SYS_ADMIN, CAP_PERFMON, unprivileged BPF disabled, BPF stats enabled
Syscalls bpf(), perf_event_open()
JIT enabled, hardened, kallsyms, memory limit, CONFIG_BPF_JIT_ALWAYS_ON
Filesystems tracefs, debugfs, securityfs, bpffs (gated tracefs/bpffs checks verify the filesystem is mounted with the expected superblock magic)
Custom mount gates any path + superblock magic via RequireMount
Namespaces initial user namespace, initial PID namespace
Parameterized workload requirements program type, map type, helper-per-program-type via requirement items
ELF-derived requirements program/map types and helper-per-program requirements via FromELF
Mitigation context Spectre v1/v2 vulnerability status
Kernel config CONFIG_BPF_LSM, CONFIG_IMA, CONFIG_DEBUG_INFO_BTF, CONFIG_FPROBE, any CONFIG_*

Stability

Pre-1.0. The public API may change between minor versions; breaking changes are called out explicitly in CHANGELOG.md. The FromELF contract (signature, determinism, fail-closed semantics) is frozen — see CONTRIBUTING.md.

Requirements

  • Linux for runtime probing/checking (uses Linux-specific syscalls and sysfs).
  • FromELF is parser-only and works on any platform.
  • Some probes require CAP_BPF or CAP_SYS_ADMIN.

Contributing

See CONTRIBUTING.md for the API model, the feature-addition checklist, and the development workflow.

License

Apache License 2.0.

About

Can my eBPF tool actually run? If not, what exactly needs to change?

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors