I am new to eBPF and currently trying to send all the executed commands with arguments in the userspace using a perf map.
I manage to send most of my data, but not the one accessed with bpf_probe_read_str
. Print the output in console works, but i don't know where to look for to forward ctx->argv
to the userspace after reading it from kernel.
Maybe am i supposed to this solution but copy all argv item manually ?
My code is based on liz's chapter 7 tuto
struct sys_enter_execve
{
// ...
char **argv;
};
struct data_t
{
// ...
char **argv;
};
SEC("tp/syscalls/sys_enter_execve")
int tp_sys_enter_execve(struct sys_enter_execve *ctx)
{
struct data_t data = {};
// ...
for (int i = 0; i < sizeof(ctx->argv); i++)
{
char *arg = NULL;
bpf_probe_read_user_str(&arg, sizeof(arg), &ctx->argv[i]);
data.argv[i] = arg; // Lead to the below error
// bpf_map_update_elem(&argv, &i, &arg, BPF_ANY); // Another solution that lead to infinite loop for the verifier
bpf_printk("arg%d: %s ", i, arg); // Works and print the correct sting
}
bpf_perf_event_output(ctx, &output, BPF_F_CURRENT_CPU, &data, sizeof(data));
return 0;
}
Below is the error from data.argv[i] = arg;
42: (85) call bpf_probe_read_user_str#114 ; R0=scalar(smin=-4095,smax=8) fp-72=mmmmmmmm
; data.argv[i] = arg;
43: (79) r1 = *(u64 *)(r10 -72) ; R1_w=scalar() R10=fp0 fp-72=mmmmmmmm
; data.argv[i] = arg;
44: (79) r2 = *(u64 *)(r10 -8) ; R2_w=P0 R10=fp0 fp-8=00000000
; data.argv[i] = arg;
45: (7b) *(u64 *)(r2 +0) = r1
R2 invalid mem access 'scalar'
processed 43 insns (limit 1000000) max_states_per_insn 0 total_states 3 peak_states 3 mark_read 3
Failed to load BPF object
I tried the alternantive solution to manually copy all args into an hashmap with bpf_map_update_elem(&argv, &i, &arg, BPF_ANY);
but the verifier can't load the program and send the below error
62: (85) call bpf_trace_printk#6
; for (int i = 0; i < sizeof(ctx->argv); i++)
infinite loop detected at insn 63
processed 97 insns (limit 1000000) max_states_per_insn 1 total_states 6 peak_states 6 mark_read 4
What did i miss in the documentation ? Thanks ✌️
So there were few confusion i had and it explain why i could not fix this problem. I'll give more details below.
I think the error
invalid mem access 'scalar'
means that the verifier can't determine the size of a char pointer to check that the size of all variables stay in 512 bytes. Basically to fix this was just to fix the size of my variable fromchar **argv;
tochar[8][50]
. I have noticed that the length ofctx->argv
was always 8 so i took this value. Then the second mistake was to make sure the value was safe usingbpf_probe_read
beforebpf_probe_read_str
So the final code look like this.
I hope it could help for your code.
Happy coding ✌️