aya-rs / aya

Aya is an eBPF library for the Rust programming language, built with a focus on developer experience and operability.
https://aya-rs.dev/book/
Apache License 2.0
3.23k stars 289 forks source link

task_struct generated by aya-tool is not portable from Linux 6.4 to Linux 6.1 #722

Open taoky opened 1 year ago

taoky commented 1 year ago

Environment: Arch Linux, Linux 6.4.7

MRE:

  1. Create a kprobe project with aya-template, attaching __x64_sys_execve
  2. Use aya-tool to generate vmlinux: aya-tool generate task_struct > aya-co-re-issue-ebpf/src/vmlinux.rs
  3. eBPF program:
#![no_std]
#![no_main]

use aya_bpf::{macros::kprobe, programs::ProbeContext, helpers::{bpf_get_current_task, bpf_probe_read_kernel}};

mod vmlinux;
use aya_log_ebpf::info;
use vmlinux::task_struct;

#[kprobe]
pub fn aya_co_re_issue(ctx: ProbeContext) -> u32 {
    match unsafe { try_aya_co_re_issue(ctx) } {
        Ok(ret) => ret,
        Err(ret) => ret,
    }
}

unsafe fn try_aya_co_re_issue(ctx: ProbeContext) -> Result<u32, u32> {
    let task = bpf_get_current_task() as *const task_struct;
    let parent = bpf_probe_read_kernel(&(*task).real_parent).map_err(|x| x as u32)?;
    let ppid = bpf_probe_read_kernel(&(*parent).tgid).map_err(|x| x as u32)? as u32;
    info!(&ctx, "My parent: {}", ppid);
    Ok(0)
}

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    unsafe { core::hint::unreachable_unchecked() }
}
  1. Compile and it works on current kernel (Shows "My parent: xxx" when executing new programs).
  2. Copy the project to a Debian 12 VM (Linux 6.1.0 for now), recompile and it does not work (shows nothing).
  3. Regenerate vmlinux in Debian 12, recompile, and it works again.

By debugging it seems that the error is caused by:

// accessing task->real_parent->tgid
let ppid = bpf_probe_read_kernel(&(*parent).tgid).map_err(|x| x as u32)? as u32;

Is it an expected behavior, or some bugs when generating vmlinux?

alessandrod commented 1 year ago

This is expected behaviour, aya-ebpf (the kernel side crate) does not support CORE relocations yet

taoky commented 1 year ago

This is expected behaviour, aya-ebpf (the kernel side crate) does not support CORE relocations yet

Thanks for your reply. I'm still curious that how aya supports CO-RE now. Would it work if I don't recompile and just copy eBPF binary compiled from Linux 6.4 to machines running Linux 6.1 in this case?

taoky commented 1 year ago

I have read https://facebookmicrosites.github.io/bpf/blog/2020/02/19/bpf-portability-and-co-re.html#reading-kernel-structures-fields again and it looks like some special functions like bpf_core_read() are required to utilize CO-RE when reading kernel structure’s fields...