-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Detect eBPF features without relying on kernel version checks
Kernel version checks are unreliable: * Features differ across architectures. * Linux distros tend to backport features to their stable/LTS kernels. Instead of relying on version, use small probes (written in eBPF assembly) to figure out what features are available.
- Loading branch information
1 parent
45cc3d3
commit 107cc32
Showing
21 changed files
with
591 additions
and
289 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
|
||
#pragma once | ||
|
||
#include "common.bpf.h" | ||
|
||
static __always_inline struct task_struct *get_current_task() { | ||
#ifdef FEATURE_TASK_BTF | ||
return bpf_get_current_task_btf(); | ||
#else | ||
return (struct task_struct*)bpf_get_current_task(); | ||
#endif | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use aya_ebpf_bindings::bindings::{BPF_DW, BPF_JEQ, BPF_REG_0, BPF_REG_1, BPF_REG_10, BPF_XCHG}; | ||
use aya_obj::generated::bpf_insn; | ||
use log::warn; | ||
|
||
use super::{load_program, BpfProgType}; | ||
use crate::insn; | ||
|
||
/// eBPF program bytecode with simple atomic operations. | ||
fn bpf_prog_atomic() -> Vec<bpf_insn> { | ||
vec![ | ||
// val = 3; | ||
insn::bpf_st_mem(BPF_DW as u8, BPF_REG_10 as u8, -8, 3), | ||
// old = atomic_xchg(&val, 4); | ||
insn::bpf_mov64_imm(BPF_REG_1 as u8, 4), | ||
insn::bpf_atomic_op( | ||
BPF_DW as u8, | ||
BPF_XCHG, | ||
BPF_REG_10 as u8, | ||
BPF_REG_1 as u8, | ||
-8, | ||
), | ||
// if (old != 3) exit(1); | ||
insn::bpf_jmp_imm(BPF_JEQ as u8, BPF_REG_1 as u8, 3, 2), | ||
insn::bpf_mov64_imm(BPF_REG_0 as u8, 1), | ||
insn::bpf_exit_insn(), | ||
// if (val != 4) exit(2); | ||
insn::bpf_ldx_mem(BPF_DW as u8, BPF_REG_0 as u8, BPF_REG_10 as u8, -8), | ||
insn::bpf_jmp_imm(BPF_JEQ as u8, BPF_REG_0 as u8, 4, 2), | ||
insn::bpf_mov64_imm(BPF_REG_0 as u8, 2), | ||
insn::bpf_exit_insn(), | ||
// exit(0); | ||
insn::bpf_mov64_imm(BPF_REG_0 as u8, 0), | ||
insn::bpf_exit_insn(), | ||
] | ||
} | ||
|
||
/// Checks whether the current kernel supports atomic operations in eBPF. | ||
pub fn atomics_supported() -> bool { | ||
let insns = bpf_prog_atomic(); | ||
// Program type doesn't matter, kprobe is just the most basic one. | ||
let res = load_program(BpfProgType::BPF_PROG_TYPE_KPROBE, insns); | ||
match res { | ||
Ok(_) => true, | ||
Err(e) => { | ||
warn!("Atomic operations in eBPF are not supported by the kernel: {e}"); | ||
false | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use aya_ebpf_bindings::bindings::BPF_REG_0; | ||
use aya_obj::generated::bpf_insn; | ||
use log::warn; | ||
|
||
use super::{load_program, BpfProgType}; | ||
use crate::insn; | ||
|
||
/// eBPF program bytecode with a simple function call (with `bpf_emit_call` | ||
/// instruction) to the function with the given ID. | ||
fn bpf_prog_func_id(func_id: u32) -> Vec<bpf_insn> { | ||
vec![ | ||
insn::bpf_emit_call(func_id), | ||
insn::bpf_mov64_imm(BPF_REG_0 as u8, 0), | ||
insn::bpf_exit_insn(), | ||
] | ||
} | ||
|
||
/// Checks whether the provided `func_id` for the given `prog_type` is | ||
/// supported by the current kernel, by loading a minimal program trying to use | ||
/// it. | ||
/// | ||
/// Similar checks are performed by [`bpftool`]. | ||
/// | ||
/// [`bpftool`]: https://github.com/torvalds/linux/blob/v6.8/tools/bpf/bpftool/feature.c#L534-L544 | ||
pub fn func_id_supported(func_id: u32, prog_type: BpfProgType) -> bool { | ||
let insns = bpf_prog_func_id(func_id); | ||
let res = load_program(prog_type, insns); | ||
match res { | ||
Ok(_) => true, | ||
Err(err) => { | ||
warn!("Function {func_id} in program type {prog_type:?} not supported: {err}"); | ||
false | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.