Kernel4.19 failed to read data using bpf_probe_read_user
- Dominant language
- C
- Stars
- 22.7k
- Forks
- 4.1k
- Avg merge
- 10d 4h
- Merged PRs (30d)
- 3
Description
Kernel4.19 failed to read data using bpf_probe_read_user
`from bcc import BPF
BPF_CODE = """
#include
struct probe_open_data_t {
u64 timestamp_ns;
u32 pid;
u32 tid;
u32 uid;
char pathname[256];
int flags;
};
BPF_PERCPU_ARRAY(open_data, struct probe_open_data_t, 1);
BPF_PERF_OUTPUT(perf_open);
// int open(const char* pathname, int flags, ...)
int probe_hook_open_enter(struct pt_regs *ctx) {
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid >> 32;
u32 tid = (u32)pid_tgid;
u32 uid = bpf_get_current_uid_gid();
u64 ts = bpf_ktime_get_ns();
PID_FILTER
TID_FILTER
UID_FILTER
char *pathname = (char *)PT_REGS_PARM1(ctx);
int flags = PT_REGS_PARM2(ctx);
u32 zero = 0;
struct probe_open_data_t *data = open_data.lookup(&zero);
if (!data)
return 0;
data->timestamp_ns = ts;
data->pid = pid;
data->tid = tid;
data->uid = uid;
data->flags = flags;
int ret = bpf_probe_read_user(data->pathname, sizeof(data->pathname), pathname);
perf_open.perf_submit(ctx, data, sizeof(struct probe_open_data_t));
return 0;
}
"""
class BPFHooker:
def __init__(self, library: str, uid: int, pid: int = -1, tid: int = -1) -> None:
self.uid = uid
self.pid = pid
self.tid = tid
self.library = library
self.bpf_module = None # type: BPF
def hook(self):
text = BPF_CODE
if self.pid > 0:
text = text.replace('PID_FILTER', f'if (pid != {self.pid}) {{ return 0; }}')
else:
text = text.replace('PID_FILTER', '')
if self.tid > 0:
text = text.replace('TID_FILTER', f'if (tid != {self.tid}) {{ return 0; }}')
else:
text = text.replace('TID_FILTER', '')
if self.uid > 0:
text = text.replace('UID_FILTER', f'if (uid != {self.uid}) {{ return 0; }}')
else:
text = text.replace('UID_FILTER', '')
self.bpf_module = BPF(text=text)
self.bpf_module.attach_uprobe(
name=self.library,
sym='open',
fn_name='probe_hook_open_enter',
pid=self.pid,
)
print('attach end')
def print_event(self, ctx, data, size):
event = self.bpf_module['perf_open'].event(data)
# print(f'[print_event] event => {event}')
# print(
# f'[open] {event.uid} {event.pid} {event.tid} '
# f'pathname: {event.pathname.decode("utf-8")} flags: {hex(event.flags)}'
# )
print(f'[open] {event.pathname.decode("utf-8")}')
def show(self):
self.bpf_module["perf_open"].open_perf_buffer(self.print_event)
while 1:
try:
self.bpf_module.perf_buffer_poll()
except KeyboardInterrupt:
exit()
def main():
uid = `0`
library = "/apex/com.android.runtime/lib64/bionic/libc.so"
bpf_hooker = BPFHooker(library, uid)
bpf_hooker.hook()
bpf_hooker.show()
if __name__ == '__main__':
main()`
Output information as follows:
root@localhost:~/project/hookopen# python open.py
attach end
[open]
[open]
[open]
[open]
[open]
[open]
[open]
[open]
[open]
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the supplied Python reproducer, especially BPFHooker.hook and the probe_hook_open_enter entry point containing bpf_probe_read_user. Run it on Kernel 4.19 and inspect the helper's behavior and BCC compatibility. Done means the reported open events contain the expected pathname instead of empty output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, linux, python
- Domain
- observability, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100