iovisor / iovisor/bcc

sys_read kprobe and tracepoint return 4 as file descriptor

Open
#3,543 1 comment 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

Hi,

I'm rather new with bpf and need some help related to attaching kprobe or adding tracepoint.
Here is my bpf code :

**file bpf_sys_reada.h:**
```
#include

const std::string BPF_PROGRAM = R"(
#include
#include

BPF_ARRAY(target_pid, u32, 1);

static bool match_target_pid()
{
int key = 0, *val, tpid, cpid;

val = target_pid.lookup(&key);
if (!val)
return false;

tpid = *val;
cpid = bpf_get_current_pid_tgid() >> 32;

if (tpid == 0 || tpid != cpid)
return false;
return true;
}

TRACEPOINT_PROBE(syscalls, sys_enter_read)
{
if(!match_target_pid())
goto EXIT;

bpf_trace_printk("sys_enter_read() : args->fd=[%d], args->buf=[%x], args->count=[%d]\n", args->fd, args->buf, args->count);
EXIT:
return 0;
}

long syscall__read(struct pt_regs *ctx,
unsigned int fd, char __user *buf, size_t count)
{
if(!match_target_pid())
goto EXIT;

bpf_trace_printk("syscall__read() invoked, fd=[%x], buf=[%x], count=[%d]\n", fd, buf, count);

EXIT:
return 0;
}

long syscall__read_ret(struct pt_regs *ctx)
{
if(!match_target_pid())
goto EXIT;

int ret = (int)PT_REGS_RC(ctx);
if (ret < 0)
goto EXIT;

bpf_trace_printk("syscall__read_ret() invoked, bytes=[%d]\n", ret);

EXIT:
return 0;
}

)";
```

I'm using C++ and attach tracepopint as :
```
auto rc = bpf.attach_tracepoint("syscalls:sys_enter_read", "tracepoint__syscalls__sys_enter_read");
if (rc.code() != 0)
{
std::cerr << rc.msg() << "\n";
return EXIT_FAILURE;
}
```

and attach kprobe as :
```
auto rc = bpf.attach_kprobe(_fnname, _probe_name, 0, type, 0);
if (rc.code() != 0)
{
std::cerr << rc.msg() << std::endl;
throw std::runtime_error("failed to attach probe [" + _probe_name + "]");
}
```

I don't provide the full C++ code as I have implemented a bunch of wrappers with extra logging.
When I run my test app and use openssl to emulate read operations, I can see both tracepoint and kprobe being hooked but the output is rather confusing :
```
openssl-29521 [022] .... 2832.700634: 0: sys_enter_read() : args->fd=[0], args->buf=[22be0410], args->count=[16384]
openssl-29521 [022] .... 2832.700642: 0: syscall__read() invoked, fd=[0], buf=[22be0410], count=[16384]
openssl-29521 [022] d... 2832.700647: 0: syscall__read_ret() invoked, bytes=[1]
openssl-29521 [022] .... 2832.700659: 0: sys_enter_read() : args->fd=[4], args->buf=[22beb6f3], args->count=[5]
openssl-29521 [022] .... 2832.700660: 0: syscall__read() invoked, fd=[4], buf=[22beb6f3], count=[5]
openssl-29521 [022] d... 2832.700783: 0: syscall__read_ret() invoked, bytes=[5]
openssl-29521 [022] .... 2832.700794: 0: sys_enter_read() : args->fd=[4], args->buf=[22beb6f8], args->count=[278]
openssl-29521 [022] .... 2832.700797: 0: syscall__read() invoked, fd=[4], buf=[22beb6f8], count=[278]
openssl-29521 [022] d... 2832.700800: 0: syscall__read_ret() invoked, bytes=[278]
openssl-29521 [022] .... 2832.701025: 0: sys_enter_read() : args->fd=[4], args->buf=[37cf15c0], args->count=[64]
openssl-29521 [022] .... 2832.701032: 0: syscall__read() invoked, fd=[4], buf=[37cf15c0], count=[64]
openssl-29521 [022] d... 2832.701035: 0: syscall__read_ret() invoked, bytes=[0]
```
But `fd` is always 4 and I hardly can understand why it's 4 always in both kprobe hook and tracepoint.
At the same time, `count` looks good and keeps a number of bytes passed to syscall.

Please, help to understand if I'm doing something wrong or how can I get file descriptor passed to `sys_read` ?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with bpf_sys_reada.h and compare the sys_enter_read tracepoint arguments with the syscall__read kprobe signature and syscall__read_ret handler. Reproduce the openssl read operations and inspect the trace output alongside the attach_tracepoint and attach_kprobe calls. Done means explaining the observed fd values and identifying how to obtain the file descriptor passed to read.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, cpp, linux
Domain
observability, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.