我正在尝试编写一个BPF程序,用于检查调用tty_write
内核函数的任何进程的会话ID。为了检索ID,我需要从指向当前task_struct
的指针跟踪许多字段,但是从指向当前任务的指针检索group_leader
指针似乎是错误的,因为偏移来自当前任务指针太大。我的BPF程序代码如下:
SEC("kprobe/tty_write")
int kprobe__tty_write(struct pt_regs *ctx)
{
struct task_struct *task;
struct task_struct *group_leader;
struct pid_link pid_link;
struct upid upid;
int sessionid;
// get current sessionid
task = (struct task_struct *)bpf_get_current_task();
bpf_probe_read(&group_leader, sizeof(group_leader), (void *)task->group_leader);
bpf_probe_read(&pid_link, sizeof(pid_link), (void *)(group_leader->pids + PIDTYPE_SID));
bpf_probe_read(&upid, sizeof(upid), (void *)pid_link.pid->numbers);
sessionid = upid.nr;
// do stuff with sessionid
return 0;
}
此操作失败,并显示以下错误。注意我使用gobpf's elf包来加载已编译的程序:
failed to load BPF module: error while loading "kprobe/tty_write" (permission denied):
0: (bf) r6 = r1
1: (85) call bpf_get_current_task#35
2: (79) r3 = *(u64 *)(r0 +1464)
R0 invalid mem access 'inv'
我如何解决这个问题,原因是什么?我认为这可能是由于堆栈大小的512字节限制,但我不是为什么在这种情况下这很重要。
uname -a
:Linux ubuntu1710 4.13.0-32-generic#35-Ubuntu SMP Thu Jan 25 09:13:46 UTC 2018 x86_64 x86_64 x86_64 GNU / Linux
答案 0 :(得分:2)
我不认为这是一个偏移太大的问题。 字段随机化的问题会影响 Linux 4.13 中的struct task_struct
。
您可以在#include
s:
#define randomized_struct_fields_start struct {
#define randomized_struct_fields_end };
您的第一个bpf_probe_read
存在第二个问题。第三个参数需要是一个指向要检索的值的指针(这里是指向指针的指针):
bpf_probe_read(&group_leader, sizeof(group_leader), &task->group_leader);