tetragon
tetragon copied to clipboard
bpf: replace arch-specific pt_regs assumptions with bpf co-re macros
Our eBPF code makes some arch-specific assumptions about the layout of struct pt_regs. We need to refactor this to use BPF CO-RE macros to make multi-arch support work properly for our kprobes.
Related, let's add a CI lint job that bans the direct use of pt_regs in the future.
Edited:
I found the definition of
https://github.com/cilium/tetragon/blob/735c3dd6dba5b7a068cf29cd37d603cb8c0c2058/bpf/lib/bpf_helpers.h#L51
So to fix this issue, we only need to replace arguments with _()
macro?
But why not directly call bpf_core_read
instead? This macro seems ambiguous :)
Moreover, in the
https://github.com/cilium/tetragon/blob/735c3dd6dba5b7a068cf29cd37d603cb8c0c2058/bpf/process/bpf_process_event.h#L545
It seems that nsproxy
, net_ns
and kn
are unnecessary, they can be removed by BPF_CORE_READ
or BPF_CORE_READ_INTO
macro
@Forsworns the registers are different based on the arch and we are reading x86 specific registers here so its more work than simply converting to bpf_core_read.
I'll check it tomorrow, it's too late in my timezone now :) I guess a bpf_core_field_exists()
may be enough.
BTW, how do you think of replacing customized _()
to explicit core signatures in the PR above... I don't know if it is better
I'm a bit partial to _() because I'm used to it. I think fixing the pt_regs so it works correctly on ARM should be done first. I can probably dig up the bpf macros to find the arch.
@jrfastab
I guess you mean pt_regs that is only specific to x86 here https://github.com/cilium/tetragon/blob/main/bpf/process/generic_calls.h#L102-L118 ?
if (config->syscall) {
struct pt_regs *_ctx;
_ctx = (struct pt_regs *)ctx->di;
if (!_ctx)
return 0;
probe_read(&e->a0, sizeof(e->a0), &_ctx->di);
probe_read(&e->a1, sizeof(e->a1), &_ctx->si);
probe_read(&e->a2, sizeof(e->a2), &_ctx->dx);
probe_read(&e->a3, sizeof(e->a3), &_ctx->r10);
probe_read(&e->a4, sizeof(e->a4), &_ctx->r8);
} else {
e->a0 = ctx->di;
e->a1 = ctx->si;
e->a2 = ctx->dx;
e->a3 = ctx->cx;
e->a4 = ctx->r8;
}
I'm a bit partial to _() because I'm used to it. I think fixing the pt_regs so it works correctly on ARM should be done first. I can probably dig up the bpf macros to find the arch.
@jrfastab you mean these macros
https://github.com/torvalds/linux/blob/master/tools/lib/bpf/bpf_tracing.h ? is it simple as include the bpf_tracing.h
and include an arm64 vmlinux.h ? like similar to pwru arm64 support? https://github.com/cilium/pwru/commit/303ea8d89d18c4810c220c85b6e8cb8c7818c508
@vincentmli yes! that's what I did in the #209
Are there any other known places that we should use the CO-RE macros, or can we close this issue?
For me, this thing is done, otherwise, the arm64 progs would not compile! :)