Почему я не могу получить указатель Task_struct родительского процесса в программе libbpf?Linux

Ответить
Anonymous
 Почему я не могу получить указатель Task_struct родительского процесса в программе libbpf?

Сообщение Anonymous »

Код: Выделить всё

#include "vmlinux.h"
#include 

typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef int pid_t;

#include "execsnoop.h"

// Define a hash map to store events
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 10240);  // Maximum number of entries in the hash map
__type(key, pid_t);          // Key type: PID
__type(value, struct event); // Value type: event
} execs SEC(".maps");

// Define a perf event map
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(u32));
__uint(value_size, sizeof(u32));
} events SEC(".maps");

SEC("tracepoint/syscalls/sys_enter_execve")
int tracepoint__syscalls__sys_enter_execve(
struct trace_event_raw_sys_enter *ctx) {
static const struct event empty_event = {};

// Get current process ID and timestamp
u64 id = bpf_get_current_pid_tgid();
pid_t pid = (pid_t)id;
u64 ts = bpf_ktime_get_ns();

// Get the parent PID of the current process
struct task_struct *task = (struct task_struct *)bpf_get_current_task();
pid_t parent_pid = 0;

if (task != NULL) {
if (task->real_parent != NULL) {
parent_pid = task->real_parent->tgid;
}
}

// Insert into the hash map only if the PID doesn't exist yet
if (bpf_map_update_elem(&execs, &pid, &empty_event, BPF_NOEXIST) != 0) {
return 0;
}

struct event *event = bpf_map_lookup_elem(&execs, &pid);
if (!event) {
return 0;
}

// Update event data
event->pid = pid;
event->ppid = parent_pid;
event->args_count = 0;
event->args_size = 0;
event->start_timestamp = ts;
bpf_get_current_comm(&event->comm, sizeof(event->comm));

unsigned int ret = 0;

// Get additional arguments
event->args_count++;
#pragma unroll
for (int i = 1; i < TOTAL_MAX_ARGS; i++) {
char *argp;
bpf_probe_read_user(&argp, sizeof(argp), &((char **)(ctx->args[1]))[i]);
if (!argp) {
break; // Stop if there are no more arguments
}

if (event->args_size > LAST_ARG) {
break; // Stop if we exceed the max argument size
}

ret =
bpf_probe_read_user_str(&event->args[event->args_size], ARGSIZE, argp);
if (ret > ARGSIZE) {
break; // Stop if argument string is too large
}

event->args_count++;
event->args_size += ret;
}

// Check if there are more arguments beyond the max
char *extra_argp;
bpf_probe_read_user(&extra_argp, sizeof(extra_argp),
&((char **)(ctx->args[1]))[TOTAL_MAX_ARGS]);
if (extra_argp) {
event->args_count++; // Count extra arguments if they exist
}

return 0;
}

// Tracepoint for sys_exit_execve
SEC("tracepoint/syscalls/sys_exit_execve")
int tracepoint__syscalls__sys_exit_execve(
struct trace_event_raw_sys_exit *ctx) {
u64 id = bpf_get_current_pid_tgid();
pid_t pid = (pid_t)id;
u64 ts = bpf_ktime_get_ns();

struct event *event = bpf_map_lookup_elem(&execs, &pid);
if (!event) {
return 0;
}

// Update event data (return value and end timestamp)
event->retval = ctx->ret;
event->end_timestamp = ts;

// Get the process name (comm)
bpf_get_current_comm(&event->comm, sizeof(event->comm));

// Submit the event to the perf event map
size_t len = EVENT_SIZE(event);
if (len real_parent != NULL) {
parent_pid = task->real_parent->tgid;
}
}
сообщение об ошибке

Код: Выделить всё

libbpf: prog 'tracepoint__syscalls__sys_enter_execve': BPF program load failed: Permission denied
libbpf: prog 'tracepoint__syscalls__sys_enter_execve': -- BEGIN PROG LOAD LOG --
0: R1=ctx() R10=fp0
; int tracepoint__syscalls__sys_enter_execve( @ execsnoop.bpf.c:26
0: (bf) r6 = r1                       ; R1=ctx() R6_w=ctx()
; u64 id = bpf_get_current_pid_tgid(); @ execsnoop.bpf.c:31
1: (85) call bpf_get_current_pid_tgid#14      ; R0_w=scalar()
; pid_t pid = (pid_t)id; @ execsnoop.bpf.c:32
2: (63) *(u32 *)(r10 -4) = r0         ; R0_w=scalar() R10=fp0 fp-8=mmmm????
; u64 ts = bpf_ktime_get_ns(); @ execsnoop.bpf.c:33
3: (85) call bpf_ktime_get_ns#5       ; R0_w=scalar()
4: (bf) r8 = r0                       ; R0_w=scalar(id=1) R8_w=scalar(id=1)
5: (b7) r9 = 0                        ; R9_w=0
; struct task_struct *task = (struct task_struct *)bpf_get_current_task(); @ execsnoop.bpf.c:36
6: (85) call bpf_get_current_task#35          ; R0=scalar()
; if (task != NULL) { @ execsnoop.bpf.c:39
7: (15) if r0 == 0x0 goto pc+4        ; R0=scalar(umin=1)
; if (task->real_parent != NULL) { @ execsnoop.bpf.c:40
8: (79) r1 = *(u64 *)(r0 +1584)
R0 invalid mem access 'scalar'
processed 9 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1
-- END PROG LOAD LOG --
libbpf: prog 'tracepoint__syscalls__sys_enter_execve': failed to load: -13
libbpf: failed to load object 'execsnoop_bpf'
libbpf: failed to load BPF skeleton 'execsnoop_bpf': -13
Failed to load and verify BPF skeleton
Кроме того, я получаю файл дампа vmlinux.h с помощью bpftool btf /sys/kernel/btf/vmlinux в формате c > vmlinux.h, проблем быть не должно (я подумай...)

Подробнее здесь: https://stackoverflow.com/questions/791 ... pf-program
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»