iovisor / iovisor/bcc

Kernel4.19 failed to read data using bpf_probe_read_user

Open
#5,370 2 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.