Skip to content

Commit e16f61a

Browse files
yinjipingsharang
authored andcommitted
fix: agent - eBPF Some kernels cannot hook file r/w interfaces
We found that certain kernel versions (e.g., 5.10.134-18.al8.x86_64) cannot hook into ksys_pwrite64() using fentry/fexit. This is likely due to kernel optimization during compilation, where the hook address does not match the actual function entry point. This issue can be observed with bpftrace, where the hook appears to succeed but no data is collected. sudo bpftrace -e ' kprobe:ksys_pwrite64 { printf("PID %d called ksys_pwrite64(fd=%d, buf=0x%x, count=%d, pos=%d)\n", pid, arg0, arg1, arg2, arg3); } ' Attaching 1 probe... To work around this, we use tracepoint-based interfaces instead.
1 parent 77cefb4 commit e16f61a

File tree

3 files changed

+29
-75
lines changed

3 files changed

+29
-75
lines changed

agent/src/ebpf/kernel/files_rw.bpf.c

-58
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ KPROG(do_preadv) (struct pt_regs *ctx) {
218218
return do_sys_enter_pread(fd, SYSCALL_FUNC_PREADV);
219219
}
220220
#else
221-
#ifndef LINUX_VER_KFUNC
222221
// /sys/kernel/debug/tracing/events/syscalls/sys_enter_pread64/format
223222
TP_SYSCALL_PROG(enter_pread64) (struct syscall_comm_enter_ctx *ctx) {
224223
int fd = ctx->fd;
@@ -236,19 +235,6 @@ TP_SYSCALL_PROG(enter_preadv2) (struct syscall_comm_enter_ctx *ctx) {
236235
int fd = ctx->fd;
237236
return do_sys_enter_pread(fd, SYSCALL_FUNC_PREADV2);
238237
}
239-
#else
240-
KFUNC_PROG(ksys_pread64, unsigned int fd, char __user *buf, size_t count,
241-
loff_t pos)
242-
{
243-
return do_sys_enter_pread(fd, SYSCALL_FUNC_PREAD64);
244-
}
245-
246-
KFUNC_PROG(do_preadv, unsigned long fd, const struct iovec __user *vec,
247-
unsigned long vlen, loff_t pos, rwf_t flags)
248-
{
249-
return do_sys_enter_pread(fd, SYSCALL_FUNC_PREADV);
250-
}
251-
#endif /* LINUX_VER_KFUNC */
252238
#endif /* SUPPORTS_KPROBE_ONLY */
253239

254240
static __inline int do_sys_exit_pread(void *ctx, ssize_t bytes_count)
@@ -281,7 +267,6 @@ KRETPROG(do_preadv) (struct pt_regs *ctx) {
281267
return do_sys_exit_pread((void *)ctx, bytes_count);
282268
}
283269
#else
284-
#ifndef LINUX_VER_KFUNC
285270
// /sys/kernel/debug/tracing/events/syscalls/sys_exit_pwrite64/format
286271
TP_SYSCALL_PROG(exit_pread64) (struct syscall_comm_exit_ctx *ctx) {
287272
return do_sys_exit_pread((void *)ctx, (ssize_t) ctx->ret);
@@ -296,19 +281,6 @@ TP_SYSCALL_PROG(exit_preadv) (struct syscall_comm_exit_ctx *ctx) {
296281
TP_SYSCALL_PROG(exit_preadv2) (struct syscall_comm_exit_ctx *ctx) {
297282
return do_sys_exit_pread((void *)ctx, (ssize_t) ctx->ret);
298283
}
299-
#else
300-
KRETFUNC_PROG(ksys_pread64, unsigned int fd, char __user *buf, size_t count,
301-
loff_t pos, ssize_t bytes_count)
302-
{
303-
return do_sys_exit_pread((void *)ctx, bytes_count);
304-
}
305-
306-
KRETFUNC_PROG(do_preadv, unsigned long fd, const struct iovec __user *vec,
307-
unsigned long vlen, loff_t pos, rwf_t flags, ssize_t bytes_count)
308-
{
309-
return do_sys_exit_pread((void *)ctx, bytes_count);
310-
}
311-
#endif /* LINUX_VER_KFUNC */
312284
#endif /* SUPPORTS_KPROBE_ONLY */
313285

314286
// File Write Event Tracing
@@ -346,7 +318,6 @@ KPROG(do_pwritev) (struct pt_regs *ctx) {
346318
return do_sys_enter_pwrite(fd, SYSCALL_FUNC_PWRITEV);
347319
}
348320
#else
349-
#ifndef LINUX_VER_KFUNC
350321
// /sys/kernel/debug/tracing/events/syscalls/sys_enter_pwrite64/format
351322
TP_SYSCALL_PROG(enter_pwrite64) (struct syscall_comm_enter_ctx *ctx) {
352323
int fd = ctx->fd;
@@ -364,20 +335,6 @@ TP_SYSCALL_PROG(enter_pwritev2) (struct syscall_comm_enter_ctx *ctx) {
364335
int fd = ctx->fd;
365336
return do_sys_enter_pwrite(fd, SYSCALL_FUNC_PWRITEV2);
366337
}
367-
368-
#else
369-
KFUNC_PROG(ksys_pwrite64, unsigned int fd, const char __user *buf,
370-
size_t count, loff_t pos)
371-
{
372-
return do_sys_enter_pwrite(fd, SYSCALL_FUNC_PWRITE64);
373-
}
374-
375-
KFUNC_PROG(do_pwritev, unsigned long fd, const struct iovec __user *vec,
376-
unsigned long vlen, loff_t pos, rwf_t flags)
377-
{
378-
return do_sys_enter_pwrite(fd, SYSCALL_FUNC_PWRITEV);
379-
}
380-
#endif /* LINUX_VER_KFUNC */
381338
#endif /* SUPPORTS_KPROBE_ONLY */
382339

383340
// pwrite64()/pwritev()/pwritev2() exit
@@ -411,7 +368,6 @@ KRETPROG(do_pwritev) (struct pt_regs *ctx) {
411368
return do_sys_exit_pwrite((void *)ctx, bytes_count);
412369
}
413370
#else
414-
#ifndef LINUX_VER_KFUNC
415371
// /sys/kernel/debug/tracing/events/syscalls/sys_exit_pwrite64/format
416372
TP_SYSCALL_PROG(exit_pwrite64) (struct syscall_comm_exit_ctx *ctx) {
417373
return do_sys_exit_pwrite((void *)ctx, (ssize_t) ctx->ret);
@@ -426,20 +382,6 @@ TP_SYSCALL_PROG(exit_pwritev) (struct syscall_comm_exit_ctx *ctx) {
426382
TP_SYSCALL_PROG(exit_pwritev2) (struct syscall_comm_exit_ctx *ctx) {
427383
return do_sys_exit_pwrite((void *)ctx, (ssize_t) ctx->ret);
428384
}
429-
430-
#else
431-
KRETFUNC_PROG(ksys_pwrite64, unsigned int fd, const char __user *buf,
432-
size_t count, loff_t pos, ssize_t bytes_count)
433-
{
434-
return do_sys_exit_pwrite((void *)ctx, bytes_count);
435-
}
436-
437-
KRETFUNC_PROG(do_pwritev, unsigned long fd, const struct iovec __user *vec,
438-
unsigned long vlen, loff_t pos, rwf_t flags, ssize_t bytes_count)
439-
{
440-
return do_sys_exit_pwrite((void *)ctx, bytes_count);
441-
}
442-
#endif /* LINUX_VER_KFUNC */
443385
#endif /* SUPPORTS_KPROBE_ONLY */
444386

445387
PROGTP(io_event) (void *ctx) {

agent/src/ebpf/user/socket.c

+27-17
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,6 @@ static void config_probes_for_kfunc(struct tracer_probes_conf *tps)
208208
kfunc_set_sym_for_entry_and_exit(tps, "do_writev");
209209
kfunc_set_sym_for_entry_and_exit(tps, "do_readv");
210210

211-
// Probe points for file read/write operations
212-
kfunc_set_sym_for_entry_and_exit(tps, "ksys_pwrite64");
213-
kfunc_set_sym_for_entry_and_exit(tps, "ksys_pread64");
214-
kfunc_set_sym_for_entry_and_exit(tps, "do_preadv");
215-
kfunc_set_sym_for_entry_and_exit(tps, "do_pwritev");
216-
217211
#if defined(__x86_64__)
218212
kfunc_set_symbol(tps, "__x64_sys_close", false);
219213
#else
@@ -255,6 +249,22 @@ static void config_probes_for_kfunc(struct tracer_probes_conf *tps)
255249

256250
// Periodic trigger for timeout checks on cached data
257251
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_getppid");
252+
253+
// file R/W probes
254+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pread64");
255+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_preadv");
256+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pwrite64");
257+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pwritev");
258+
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_pread64");
259+
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_preadv");
260+
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_pwrite64");
261+
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_pwritev");
262+
if (!access(SYSCALL_PRWV2_TP_PATH, F_OK)) {
263+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_preadv2");
264+
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_preadv2");
265+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pwritev2");
266+
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_pwritev2");
267+
}
258268
}
259269

260270
static void config_probes_for_kprobe_and_tracepoint(struct tracer_probes_conf
@@ -304,14 +314,6 @@ static void config_probes_for_kprobe_and_tracepoint(struct tracer_probes_conf
304314
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_connect");
305315
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_recvmmsg");
306316

307-
// file R/W probes
308-
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pread64");
309-
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_preadv");
310-
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_preadv2");
311-
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pwrite64");
312-
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pwritev");
313-
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pwritev2");
314-
315317
// exit tracepoints
316318
/*
317319
* `tracepoint/syscalls/sys_exit_socket` This is currently added only to
@@ -351,13 +353,21 @@ static void config_probes_for_kprobe_and_tracepoint(struct tracer_probes_conf
351353
// Periodic trigger for timeout checks on cached data
352354
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_getppid");
353355

354-
// file R/W probes
356+
// file R/W probes
357+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pread64");
358+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_preadv");
359+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pwrite64");
360+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pwritev");
355361
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_pread64");
356362
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_preadv");
357-
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_preadv2");
358363
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_pwrite64");
359364
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_pwritev");
360-
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_pwritev2");
365+
if (!access(SYSCALL_PRWV2_TP_PATH, F_OK)) {
366+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_preadv2");
367+
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_preadv2");
368+
tps_set_symbol(tps, "tracepoint/syscalls/sys_enter_pwritev2");
369+
tps_set_symbol(tps, "tracepoint/syscalls/sys_exit_pwritev2");
370+
}
361371
}
362372

363373

agent/src/ebpf/user/socket.h

+2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424

2525
#define SYSCALL_FORK_TP_PATH "/sys/kernel/debug/tracing/events/syscalls/sys_exit_fork"
2626
#define SYSCALL_CLONE_TP_PATH "/sys/kernel/debug/tracing/events/syscalls/sys_exit_clone"
27+
#define SYSCALL_PRWV2_TP_PATH "/sys/kernel/debug/tracing/events/syscalls/sys_enter_preadv2"
2728
#define FTRACE_SYSCALLS_PATH "/sys/kernel/debug/tracing/events/syscalls"
29+
2830
/*
2931
* The `__sys_recvmmsg` interface underwent a change in its parameter list starting
3032
* from Linux kernel version 5.0. If earlier kernel versions support the `fentry/fexit`

0 commit comments

Comments
 (0)