C 从指向BPF程序中大型结构的指针检索字段时,权限被拒绝

C 从指向BPF程序中大型结构的指针检索字段时,权限被拒绝,c,bpf,ebpf,C,Bpf,Ebpf,我正在尝试编写一个BPF程序,它检查调用tty_write内核函数的任何进程的会话ID。为了检索ID,我需要在指向当前任务结构的指针后面跟随许多字段,但是从指向当前任务的指针检索组组长指针似乎有错误,因为与当前任务指针的偏移太大。我的BPF程序代码如下: SEC("kprobe/tty_write") int kprobe__tty_write(struct pt_regs *ctx) { struct task_struct *task; struct task_struct

我正在尝试编写一个BPF程序,它检查调用
tty_write
内核函数的任何进程的会话ID。为了检索ID,我需要在指向当前
任务结构
的指针后面跟随许多字段,但是从指向当前任务的指针检索
组组长
指针似乎有错误,因为与当前任务指针的偏移太大。我的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;
}
此操作失败,出现以下错误。注意:我正在使用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

我认为偏移量太大不是问题。在Linux 4.13中,字段随机化存在一个问题,影响
struct task\u struct

您可以使用不同的内核,或者在
#include
s之前放置以下内容:

#define randomized_struct_fields_start  struct {
#define randomized_struct_fields_end    };

您的第一个
bpf\u探测器读取出现第二个问题
。第三个参数需要是指向要检索的值的指针(这里是指向指针的指针):


我在我的程序顶部添加了这些定义,但我得到了相同的错误-我尝试在4.11上运行它,得到了相同的错误。这是我错过的第二个问题。我已经更新了我的答案。真棒的干杯:)我仍然得到一个0 sessionid,但我认为这是一个不同的问题,我还不明白,尽管你的解释有道理
bpf_probe_read(&group_leader, sizeof(group_leader), &task->group_leader);