sys_read kprobe and tracepoint return 4 as file descriptor
- 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