始终在BPF程序中获得0会话ID

我正在尝试编写一个BPF程序来检查调用tty_write内核函数的任何进程的会话ID。 我试图通过从当前task_struct结构中检索一个字段来做到这一点。 我的代码如下:

 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 pid pid; int sessionid; // get current sessionid task = (struct task_struct *)bpf_get_current_task(); bpf_probe_read(&group_leader, sizeof(group_leader), &task->group_leader); bpf_probe_read(&pid_link, sizeof(pid_link), group_leader->pids + PIDTYPE_SID); bpf_probe_read(&pid, sizeof(pid), pid_link.pid); sessionid = pid.numbers[0].nr; // do stuff with sessionid return 0; } 

请注意,我正在使用clang编译我的BPF程序到ELF文件并使用gobpf的 ELF包加载它。 不幸的是, sessionid的值总是为0.这是为什么? 我不认为我在4.11内核上使用bcc之前没有错误地访问会话ID(由于bcc重写的BPF程序如何,当我想自己编译程序时,我不能简单地使用相同的代码)。 用于访问sessionid的等效工作密件代码如下。 请注意,这仅适用于4.11内核,以下代码不适用于4.13内核。 上面的代码不适用于任何内核。

 #!/usr/bin/python from bcc import BPF import ctypes as ct import os import threading import time import sys prog=r""" #include  #include  #include  #include  #include  #define BUFSIZE 256 struct tty_write_t { int count; char buf[BUFSIZE]; unsigned int sessionid; }; // define maps BPF_PERF_OUTPUT(tty_writes); int kprobe__tty_write(struct pt_regs *ctx, struct file *file, const char __user *buf, size_t count) { struct task_struct *task; struct pid_link pid_link; struct pid pid; int sessionid; // get current sessionid task = (struct task_struct *)bpf_get_current_task(); bpf_probe_read(&pid_link, sizeof(pid_link), (void *)&task->group_leader->pids[PIDTYPE_SID]); bpf_probe_read(&pid, sizeof(pid), (void *)pid_link.pid); sessionid = pid.numbers[0].nr; // bpf_probe_read() can only use a fixed size, so truncate to count // in user space: struct tty_write_t tty_write = {}; bpf_probe_read(&tty_write.buf, BUFSIZE, (void *)buf); if (count > BUFSIZE) { tty_write.count = BUFSIZE; } else { tty_write.count = count; } // add sessionid to tty_write structure and submit tty_write.sessionid = sessionid; tty_writes.perf_submit(ctx, &tty_write, sizeof(tty_write)); return 0; } """ b = BPF(text=prog) BUFSIZE = 256 class TTYWrite(ct.Structure): _fields_ = [ ("count", ct.c_int), ("buf", ct.c_char * BUFSIZE), ("sessionid", ct.c_int) ] # process tty_write def print_tty_write(cpu, data, size): tty_write = ct.cast(data, ct.POINTER(TTYWrite)).contents print(str(tty_write.sessionid)) b["tty_writes"].open_perf_buffer(print_tty_write) while 1: b.kprobe_poll() 

4.11内核:

uname -a :Linux ubuntu16 4.11.0-14-generic#20~16.04.1-Ubuntu SMP Wed Aug 9 09:06:22 UTC 2017 x86_64 x86_64 x86_64 GNU / Linux

4.13内核:

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

这是因为我不了解如何为特定内核版本编译BPF程序 – 我正在使用为4.15内核安装内核头文件的Docker容器编译,但是试图在4.11内核上运行该程序。

为了解决这个问题,我使用4.11内核头文件编译了我的程序。

Interesting Posts