Documentation
¶
Overview ¶
Package kfeatures provides kernel feature detection for eBPF programs.
This package probes kernel capabilities at runtime, enabling early failure with clear, actionable error messages when requirements aren't met. It complements github.com/cilium/ebpf/features by adding BTF availability detection, security subsystem probing (LSM, IMA), kernel config parsing, capability checking, and composite feature validation with operator-facing diagnostics.
API Model ¶
kfeatures intentionally exposes two API families:
- Check for pass/fail readiness validation using Requirement items
- Probe/ProbeWith for diagnostics data collection using WithX options
Keep these families separate:
- model stable boolean gates as Feature
- model parameterized gates as Requirement item types
- keep context-only/descriptive signals probe-only unless a concrete deterministic gating policy is defined.
FromELF API contract (frozen):
- FromELF returns FeatureGroup requirement items consumable by Check
- output is deterministic (deduplicated, stable order)
- extraction scope includes program/map types and helper-per-program requirements
- unknown/unsupported ELF kinds fail closed with an error
Quick Check ¶
Validate that required kernel features are available:
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)
}
log.Fatal(err)
}
Full Probe ¶
Probe all features for diagnostics:
sf, err := kfeatures.Probe()
if err != nil {
log.Fatal(err)
}
fmt.Printf("BPF LSM program type: %v\n", sf.LSMProgramType.Supported)
fmt.Printf("BPF LSM enabled: %v\n", sf.BPFLSMEnabled.Supported)
fmt.Printf("BTF available: %v\n", sf.BTF.Supported)
fmt.Printf("Kernel: %s\n", sf.KernelVersion)
fmt.Println(sf) // human-readable summary
Selective Probing ¶
Probe only specific features to minimize overhead:
sf, err := kfeatures.ProbeWith(
kfeatures.WithProgramTypes(ebpf.LSM, ebpf.Kprobe),
kfeatures.WithSecuritySubsystems(),
kfeatures.WithCapabilities(),
)
Types ¶
ProbeResult represents the outcome of probing a single feature:
- Supported: true if the feature is available
- Error: non-nil if the probe itself failed (not just unsupported)
SystemFeatures aggregates all probe results into a single struct.
KernelConfig holds parsed kernel configuration values with support for distinguishing between =m (module) and =y (built-in) settings.
Feature represents a kernel capability that can be checked via Check.
FeatureError provides actionable diagnostics when a required feature is unavailable, including the feature name, a human-readable reason with remediation steps, and the underlying probe error if any.
Index ¶
- Variables
- func Check(required ...Requirement) error
- func FeatureNames() []string
- func ReadIMARuntimeMeasurementsCount() (int, error)
- func ResetCache()
- type ConfigValue
- type Feature
- type FeatureError
- type FeatureGroup
- type KernelConfig
- type MapTypeRequirement
- type MountRequirement
- type PreemptMode
- type ProbeOption
- func WithAll() ProbeOption
- func WithCapabilities() ProbeOption
- func WithFilesystems() ProbeOption
- func WithJIT() ProbeOption
- func WithKernelConfig() ProbeOption
- func WithLSMPath(path string) ProbeOption
- func WithMitigations() ProbeOption
- func WithNamespaces() ProbeOption
- func WithProgramTypes(types ...ebpf.ProgramType) ProbeOption
- func WithSecuritySubsystems() ProbeOption
- func WithSyscalls() ProbeOption
- type ProbeResult
- type ProgramHelperRequirement
- type ProgramTypeRequirement
- type Requirement
- type SystemFeatures
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidFeature = fmt.Errorf("not a valid Feature, try [%s]", strings.Join(_FeatureNames, ", "))
var ErrNoKernelConfig = errors.New("no kernel config found")
ErrNoKernelConfig is returned when no kernel config source is available.
var ErrUnsupportedPlatform = errors.New("probing requires Linux")
ErrUnsupportedPlatform is returned by all probe and check functions on non-Linux platforms where kernel feature detection is not possible.
Functions ¶
func Check ¶
func Check(required ...Requirement) error
Check validates the specified requirements and returns a *FeatureError for the first unsatisfied requirement, or nil if all are met.
Accepted requirement kinds:
- Feature (stable boolean gates)
- FeatureGroup (reusable requirement presets)
- ProgramTypeRequirement, MapTypeRequirement, ProgramHelperRequirement
- MountRequirement (filesystem-mounted-with-magic gate)
Check is the only gate entrypoint. Keep ProbeWith/WithX for diagnostics-only data collection, not for expressing required readiness conditions. Kernel config is always probed to provide actionable diagnostics.
func FeatureNames ¶
func FeatureNames() []string
FeatureNames returns a list of possible string values of Feature.
func ReadIMARuntimeMeasurementsCount ¶
ReadIMARuntimeMeasurementsCount returns the current IMA runtime measurement count from /sys/kernel/security/ima/runtime_measurements_count. No side effects. Useful for diagnostics and for callers building before/after probes.
func ResetCache ¶
func ResetCache()
ResetCache clears cached probe results, forcing the next Probe call to re-probe. This is primarily useful for testing.
Types ¶
type ConfigValue ¶
type ConfigValue int
ConfigValue represents a kernel configuration option's state.
const ( // ConfigNotSet means the option is not set or not found. ConfigNotSet ConfigValue = iota // ConfigModule means the option is set to =m (module). ConfigModule // ConfigBuiltin means the option is set to =y (built-in). ConfigBuiltin )
func (ConfigValue) IsBuiltin ¶
func (v ConfigValue) IsBuiltin() bool
IsBuiltin returns true if the config option is built-in (=y).
func (ConfigValue) IsEnabled ¶
func (v ConfigValue) IsEnabled() bool
IsEnabled returns true if the config option is set (either =m or =y).
func (ConfigValue) String ¶
func (v ConfigValue) String() string
type Feature ¶
type Feature int
Feature represents a kernel capability that can be checked via Check.
ENUM( bpf-lsm btf ima kprobe kprobe-multi fentry tracepoint cap-bpf cap-sys-admin cap-perfmon jit-enabled jit-hardened bpf-syscall perf-event-open sleepable-bpf trace-fs bpf-fs init-user-ns unprivileged-bpf-disabled bpf-stats-enabled ima-any-measurement-active )
const ( // FeatureBPFLSM is a Feature of type Bpf-Lsm. FeatureBPFLSM Feature = iota // FeatureBTF is a Feature of type Btf. FeatureBTF // FeatureIMA is a Feature of type Ima. FeatureIMA // FeatureKprobe is a Feature of type Kprobe. FeatureKprobe // FeatureKprobeMulti is a Feature of type Kprobe-Multi. FeatureKprobeMulti // FeatureFentry is a Feature of type Fentry. FeatureFentry // FeatureTracepoint is a Feature of type Tracepoint. FeatureTracepoint // FeatureCapBPF is a Feature of type Cap-Bpf. FeatureCapBPF // FeatureCapSysAdmin is a Feature of type Cap-Sys-Admin. FeatureCapSysAdmin // FeatureCapPerfmon is a Feature of type Cap-Perfmon. FeatureCapPerfmon // FeatureJITEnabled is a Feature of type Jit-Enabled. FeatureJITEnabled // FeatureJITHardened is a Feature of type Jit-Hardened. FeatureJITHardened // FeatureBPFSyscall is a Feature of type Bpf-Syscall. FeatureBPFSyscall // FeaturePerfEventOpen is a Feature of type Perf-Event-Open. FeaturePerfEventOpen // FeatureSleepableBPF is a Feature of type Sleepable-Bpf. FeatureSleepableBPF // FeatureTraceFS is a Feature of type Trace-Fs. FeatureTraceFS // FeatureBPFFS is a Feature of type Bpf-Fs. FeatureBPFFS // FeatureInitUserNS is a Feature of type Init-User-Ns. FeatureInitUserNS // FeatureUnprivilegedBPFDisabled is a Feature of type Unprivileged-Bpf-Disabled. FeatureUnprivilegedBPFDisabled // FeatureBPFStatsEnabled is a Feature of type Bpf-Stats-Enabled. FeatureBPFStatsEnabled // FeatureIMAAnyMeasurementActive is a Feature of type Ima-Any-Measurement-Active. FeatureIMAAnyMeasurementActive )
func FeatureValues ¶
func FeatureValues() []Feature
FeatureValues returns a list of the values for Feature
func ParseFeature ¶
ParseFeature attempts to convert a string to a Feature.
func (*Feature) AppendText ¶
AppendText appends the textual representation of itself to the end of b (allocating a larger slice if necessary) and returns the updated slice.
Implementations must not retain b, nor mutate any bytes within b[:len(b)].
func (Feature) IsValid ¶
IsValid provides a quick way to determine if the typed value is part of the allowed enumerated values
func (Feature) MarshalText ¶
MarshalText implements the text marshaller method.
func (*Feature) UnmarshalText ¶
UnmarshalText implements the text unmarshaller method.
type FeatureError ¶
FeatureError represents an error when a required kernel feature is unavailable.
func (*FeatureError) Error ¶
func (e *FeatureError) Error() string
func (*FeatureError) Unwrap ¶
func (e *FeatureError) Unwrap() error
type FeatureGroup ¶
type FeatureGroup []Requirement
FeatureGroup is a reusable set of Requirement items.
Groups can include simple Feature values and parameterized requirements. It is a preset container, not a separate gate API family.
func FromELF ¶
func FromELF(path string) (FeatureGroup, error)
FromELF derives workload requirements from an eBPF ELF object file.
Contract:
- Signature: FromELF(path string) (FeatureGroup, error)
- Determinism: output is deduplicated and stably ordered
- Scope: extract program/map requirements and helper-per-program requirements
- Unknown handling: fail closed (return error for unsupported/unknown kinds)
Returned requirements are directly consumable by Check.
type KernelConfig ¶
type KernelConfig struct {
// Convenience fields for common checks (populated from raw).
BPFLSM ConfigValue // CONFIG_BPF_LSM
IMA ConfigValue // CONFIG_IMA
BTF ConfigValue // CONFIG_DEBUG_INFO_BTF
KprobeMulti ConfigValue // CONFIG_FPROBE (required for kprobe.multi)
JITAlwaysOn ConfigValue // CONFIG_BPF_JIT_ALWAYS_ON
Preempt PreemptMode // Derived from CONFIG_PREEMPT_*
// contains filtered or unexported fields
}
KernelConfig holds parsed kernel configuration values.
func NewKernelConfig ¶
func NewKernelConfig(raw map[string]ConfigValue) *KernelConfig
NewKernelConfig creates a KernelConfig from a raw config map. The map is copied to ensure immutability after construction.
func (*KernelConfig) Get ¶
func (kc *KernelConfig) Get(key string) ConfigValue
Get returns the ConfigValue for a kernel config key. The key should not include the CONFIG_ prefix.
func (*KernelConfig) IsSet ¶
func (kc *KernelConfig) IsSet(key string) bool
IsSet returns true if the config option is enabled (=m or =y).
type MapTypeRequirement ¶
MapTypeRequirement requires support for a specific eBPF map type.
func RequireMapType ¶
func RequireMapType(mt ebpf.MapType) MapTypeRequirement
RequireMapType creates a requirement for a map type.
type MountRequirement ¶
MountRequirement requires that Path is mounted with a filesystem whose superblock magic equals Magic. Magic is the raw f_type value the kernel reports via Statfs (e.g. golang.org/x/sys/unix.BPF_FS_MAGIC for bpffs).
Use this when FeatureBPFFS / FeatureTraceFS are too restrictive: for example, bpffs mounted at a non-default path, or any other pseudo-FS the caller depends on (cgroupv2, debugfs, securityfs, tmpfs in tests, ...).
func RequireMount ¶
func RequireMount(path string, magic uint32) MountRequirement
RequireMount creates a requirement that path is mounted with a filesystem whose superblock magic equals magic.
Magic numbers live in golang.org/x/sys/unix (e.g. unix.BPF_FS_MAGIC, unix.TRACEFS_MAGIC, unix.CGROUP2_SUPER_MAGIC). Pass the raw value.
Panics if path is empty or magic is zero. Both indicate API misuse: an empty path cannot be statfs'd, and a zero magic does not correspond to any known filesystem and would silently mismatch every real mount.
type PreemptMode ¶
type PreemptMode int
PreemptMode represents the kernel preemption model.
const ( // PreemptUnknown means the preemption model could not be determined. PreemptUnknown PreemptMode = iota // PreemptNone means no forced preemption (server workloads). PreemptNone // PreemptVoluntary means voluntary preemption (desktop default). PreemptVoluntary // PreemptFull means full preemption (low-latency). PreemptFull // PreemptDynamic means runtime-switchable preemption (kernel 5.12+). PreemptDynamic )
func (PreemptMode) String ¶
func (m PreemptMode) String() string
func (PreemptMode) SupportsSleepable ¶
func (m PreemptMode) SupportsSleepable() bool
SupportsSleepable reports whether the preemption model supports sleepable BPF programs (BPF_F_SLEEPABLE). Requires full preemption or dynamic preemption.
type ProbeOption ¶
type ProbeOption func(*probeConfig)
ProbeOption configures what ProbeWith collects for diagnostics/reporting. Probe options are not readiness requirements and are intentionally separate from Requirement values consumed by Check.
func WithCapabilities ¶
func WithCapabilities() ProbeOption
WithCapabilities probes process capabilities (CAP_BPF, CAP_SYS_ADMIN, CAP_PERFMON), unprivileged BPF access status, and BPF runtime stats status.
func WithFilesystems ¶
func WithFilesystems() ProbeOption
WithFilesystems probes filesystem mounts relevant to BPF operations (tracefs, debugfs, securityfs, bpffs).
func WithJIT ¶
func WithJIT() ProbeOption
WithJIT probes BPF JIT compiler status (enabled, hardening, kallsyms, memory limit).
func WithKernelConfig ¶
func WithKernelConfig() ProbeOption
WithKernelConfig parses and includes kernel configuration.
func WithLSMPath ¶
func WithLSMPath(path string) ProbeOption
WithLSMPath sets a custom path for the LSM file. This is primarily for testing; production code uses the default /sys/kernel/security/lsm.
func WithMitigations ¶
func WithMitigations() ProbeOption
WithMitigations probes CPU vulnerability mitigations that affect BPF JIT codegen and reads CONFIG_BPF_JIT_ALWAYS_ON from kernel config.
func WithNamespaces ¶
func WithNamespaces() ProbeOption
WithNamespaces probes namespace context (user namespace, PID namespace).
func WithProgramTypes ¶
func WithProgramTypes(types ...ebpf.ProgramType) ProbeOption
WithProgramTypes probes the specified eBPF program types.
func WithSecuritySubsystems ¶
func WithSecuritySubsystems() ProbeOption
WithSecuritySubsystems probes security subsystem status (LSM list, IMA).
func WithSyscalls ¶
func WithSyscalls() ProbeOption
WithSyscalls probes availability of BPF-relevant syscalls (bpf(), perf_event_open).
type ProbeResult ¶
type ProbeResult struct {
// Supported indicates whether the feature is available.
Supported bool
// Error is non-nil if the probe itself failed (not just unsupported).
Error error
}
ProbeResult represents the outcome of a kernel feature probe.
func ProbeIMAAnyMeasurementActive ¶
func ProbeIMAAnyMeasurementActive() ProbeResult
ProbeIMAAnyMeasurementActive checks whether at least one IMA measurement rule has fired. It does not identify which func= rule caused the measurement. Exported so consumers can call it directly without going through Check.
func ProbeIMAExecMeasurementActive ¶
func ProbeIMAExecMeasurementActive() ProbeResult
ProbeIMAExecMeasurementActive checks whether an IMA measurement rule covering exec (e.g., func=BPRM_CHECK) is active by executing a fresh temporary binary and checking for a measurement count increase.
Unlike ProbeIMAAnyMeasurementActive, this probe does not use a count > 1 shortcut. It returns Supported=true only when the controlled exec stimulus increments the IMA measurement count.
func ProbeIMAFileCheckMeasurementActive ¶
func ProbeIMAFileCheckMeasurementActive() ProbeResult
ProbeIMAFileCheckMeasurementActive checks whether an IMA measurement rule covering file open (e.g., func=FILE_CHECK) is active by opening a fresh temporary file and checking for a measurement count increase.
Unlike ProbeIMAAnyMeasurementActive, this probe does not use a count > 1 shortcut. It returns Supported=true only when the controlled file-open stimulus increments the IMA measurement count.
type ProgramHelperRequirement ¶
type ProgramHelperRequirement struct {
ProgramType ebpf.ProgramType
Helper asm.BuiltinFunc
}
ProgramHelperRequirement requires that a helper is supported for a program type.
func RequireProgramHelper ¶
func RequireProgramHelper(pt ebpf.ProgramType, helper asm.BuiltinFunc) ProgramHelperRequirement
RequireProgramHelper creates a requirement for a helper/program-type pair.
type ProgramTypeRequirement ¶
type ProgramTypeRequirement struct {
Type ebpf.ProgramType
}
ProgramTypeRequirement requires support for a specific eBPF program type.
func RequireProgramType ¶
func RequireProgramType(pt ebpf.ProgramType) ProgramTypeRequirement
RequireProgramType creates a requirement for a program type.
type Requirement ¶
type Requirement interface {
// contains filtered or unexported methods
}
Requirement describes a pass/fail gate condition consumable by Check.
API boundary:
- Requirement values define what must pass.
- ProbeOption/WithX values define what ProbeWith should collect.
- Do not model probe-scope selection as requirements.
Built-in implementations include:
type SystemFeatures ¶
type SystemFeatures struct {
// Syscall availability
// BPFSyscall: Supported=true means the bpf() syscall is available.
BPFSyscall ProbeResult
// PerfEventOpen: Supported=true means the perf_event_open() syscall is available.
// Required for kprobe/tracepoint/uprobe attachment.
PerfEventOpen ProbeResult
// Program types (runtime probes via cilium/ebpf)
LSMProgramType ProbeResult
Kprobe ProbeResult
KprobeMulti ProbeResult
Tracepoint ProbeResult
Fentry ProbeResult
// BTF (BPF Type Format) for CO-RE programs
BTF ProbeResult
// Security subsystems (sysfs checks)
// These use ProbeResult because reading /sys/kernel/security/lsm can fail
// (permissions, securityfs not mounted, etc.)
BPFLSMEnabled ProbeResult
ActiveLSMs []string
// IMA detection (multiple signals for diagnostics)
// IMAEnabled is the authoritative signal: true only if "ima" is in the LSM list.
// This is required for bpf_ima_file_hash to work.
IMAEnabled ProbeResult
// IMADirectory indicates /sys/kernel/security/ima exists.
// IMA securityfs is mounted, but IMA may not be actively measuring files.
IMADirectory ProbeResult
// IMAAnyMeasurementActive indicates at least one IMA measurement rule
// has fired. It does not identify which func= rule caused the measurement.
// Checked by reading the runtime measurement count and, if needed,
// executing /bin/true to trigger a potential BPRM_CHECK rule.
// When active, IMA caches file hashes in the inode security blob.
IMAAnyMeasurementActive ProbeResult
// Process capabilities relevant to BPF operations
HasCapBPF ProbeResult // CAP_BPF (kernel 5.8+)
HasCapSysAdmin ProbeResult // CAP_SYS_ADMIN (fallback for pre-5.8 kernels)
HasCapPerfmon ProbeResult // CAP_PERFMON (perf events, tracepoints)
// Unprivileged BPF access
// Supported=true means unprivileged BPF is disabled (the common/secure default).
UnprivilegedBPFDisabled ProbeResult
// Filesystem mounts relevant to BPF operations
// TraceFS: required for kprobe/tracepoint attachment via ftrace.
TraceFS ProbeResult
// DebugFS: legacy mount point, fallback for tracefs on older kernels.
DebugFS ProbeResult
// SecurityFS: required for reading LSM state (/sys/kernel/security/*).
SecurityFS ProbeResult
// BPFFS: required for pinning BPF maps and programs (/sys/fs/bpf).
BPFFS ProbeResult
// JIT compiler status (sysctl values)
// JITEnabled: Supported=true means BPF JIT compiler is enabled.
// Values: 0=disabled, 1=enabled, 2=enabled+debug (emit to kernel log).
JITEnabled ProbeResult
// JITHardened: Supported=true means BPF JIT hardening is active.
// Values: 0=disabled, 1=enabled for unprivileged, 2=enabled for all.
JITHardened ProbeResult
// JITKallsyms: Supported=true means JIT-compiled BPF programs are exposed in /proc/kallsyms.
JITKallsyms ProbeResult
// JITLimit: the memory limit in bytes for JIT-compiled BPF programs (0 if unavailable).
JITLimit int64
// JIT always-on mode (derived from kernel config).
// When CONFIG_BPF_JIT_ALWAYS_ON=y, the BPF interpreter is disabled and
// all programs must be JIT-compiled. Forced by some Spectre mitigation policies.
JITAlwaysOn ConfigValue
// CPU vulnerability mitigations.
// Each field contains the raw mitigation string from /sys/devices/system/cpu/vulnerabilities/
// or empty if the file doesn't exist. Values like "Mitigation: ..." mean active protection.
SpectreV1 string // spectre_v1
SpectreV2 string // spectre_v2
// Kernel preemption model (derived from kernel config).
// Affects sleepable BPF programs (BPF_F_SLEEPABLE).
PreemptMode PreemptMode
// Namespace awareness.
// InInitUserNS: Supported=true means the process runs in the initial user namespace.
// BPF is often restricted in non-initial user namespaces.
InInitUserNS ProbeResult
// InInitPIDNS: Supported=true means the process runs in the initial PID namespace.
// bpf_get_current_pid_tgid() returns the PID in the current PID namespace, which
// differs from the host PID when running in a nested PID namespace.
InInitPIDNS ProbeResult
// BPF runtime statistics
// BPFStatsEnabled: Supported=true means /proc/sys/kernel/bpf_stats_enabled is non-zero.
// When enabled, the kernel collects per-program runtime stats (run count, run time).
// Useful for verifier profiling and performance debugging.
BPFStatsEnabled ProbeResult
// Kernel config (optional, may be nil if not probed)
KernelConfig *KernelConfig
// Metadata
KernelVersion string
}
SystemFeatures holds the results of all kernel feature probes.
func Probe ¶
func Probe() (*SystemFeatures, error)
Probe probes all kernel features and caches the result. Subsequent calls return the cached result without re-probing. Use ProbeNoCache if you need fresh results.
func ProbeNoCache ¶
func ProbeNoCache() (*SystemFeatures, error)
ProbeNoCache probes all kernel features without using the cache. Use this when you need fresh results, e.g., after loading kernel modules.
func ProbeWith ¶
func ProbeWith(opts ...ProbeOption) (*SystemFeatures, error)
ProbeWith probes kernel features based on the provided options. BTF and kernel version are always probed regardless of options (both are cheap). If no options are provided, only BTF and kernel version are populated.
func (*SystemFeatures) Diagnose ¶
func (sf *SystemFeatures) Diagnose(f Feature) string
Diagnose returns an enriched reason string explaining why a feature is not supported and what the operator can do to fix it.
func (*SystemFeatures) Result ¶
func (sf *SystemFeatures) Result(f Feature) (ProbeResult, bool)
Result maps a Feature to its corresponding ProbeResult in SystemFeatures. Returns false as the second value if the feature is unknown.
func (*SystemFeatures) String ¶
func (sf *SystemFeatures) String() string
String returns a human-readable summary of all probe results.