Skip to content

Commit

Permalink
tracee-ebpf: update minimal kernel version to 4.18
Browse files Browse the repository at this point in the history
  • Loading branch information
yanivagman committed Feb 18, 2021
1 parent 2001ffe commit 59312a1
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 81 deletions.
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Tracee is composed of the following sub-projects:

### Prerequisites

- Linux kernel version >= 4.14
- Linux kernel version >= 4.18
- Relevant kernel headers available under conventional location (see [Linux Headers](#Linux-Headers) section for info)
- libc, and the libraries: libelf and zlib
- clang >= 9
Expand Down
2 changes: 1 addition & 1 deletion tracee-ebpf/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Tracee-eBPF is a lightweight and easy to use tracing tool for Linux, which is fo

### Prerequisites

- Linux kernel version >= 4.14
- Linux kernel version >= 4.18
- Relevant kernel headers available under conventional location (see [Linux Headers](#Linux-Headers) section for info)
- libc, and the libraries: libelf and zlib
- clang >= 9
Expand Down
64 changes: 7 additions & 57 deletions tracee-ebpf/tracee/tracee.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ struct bpf_map_def SEC("maps") _name = { \
#endif
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
#error Minimal required kernel version is 4.14
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0)
#error Minimal required kernel version is 4.18
#endif

/*=============================== INTERNAL STRUCTS ===========================*/
Expand Down Expand Up @@ -442,11 +442,7 @@ static __always_inline u32 get_task_ppid(struct task_struct *task)
static __always_inline bool is_x86_compat(struct task_struct *task)
{
#if defined(bpf_target_x86)
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 18))
return READ_KERN(task->thread.status) & TS_COMPAT;
#else
return READ_KERN(task->thread_info.status) & TS_COMPAT;
#endif
#else
return false;
#endif
Expand Down Expand Up @@ -1366,39 +1362,15 @@ int trace_ret_##name(void *ctx) \

/*============================== SYSCALL HOOKS ==============================*/

struct trace_event_raw_sys_enter {
unsigned long long unused;
long int id;
long unsigned int args[6];
};

// include/trace/events/syscalls.h:
// TP_PROTO(struct pt_regs *regs, long id)
SEC("raw_tracepoint/sys_enter")
int tracepoint__raw_syscalls__sys_enter(
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
struct trace_event_raw_sys_enter *args
#else
struct bpf_raw_tracepoint_args *ctx
#endif
)
int tracepoint__raw_syscalls__sys_enter(struct bpf_raw_tracepoint_args *ctx)
{
args_t args_tmp = {};
int id;
int id = ctx->args[1];
struct task_struct *task = (struct task_struct *)bpf_get_current_task();

#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
void *ctx = args;
id = args->id;

args_tmp.args[0] = args->args[0];
args_tmp.args[1] = args->args[1];
args_tmp.args[2] = args->args[2];
args_tmp.args[3] = args->args[3];
args_tmp.args[4] = args->args[4];
args_tmp.args[5] = args->args[5];
#else // LINUX_VERSION_CODE
id = ctx->args[1];
#if defined(CONFIG_ARCH_HAS_SYSCALL_WRAPPER)
struct pt_regs regs = {};
bpf_probe_read(&regs, sizeof(struct pt_regs), (void*)ctx->args[0]);
Expand Down Expand Up @@ -1428,7 +1400,6 @@ struct bpf_raw_tracepoint_args *ctx
args_tmp.args[4] = ctx->args[4];
args_tmp.args[5] = ctx->args[5];
#endif // CONFIG_ARCH_HAS_SYSCALL_WRAPPER
#endif // LINUX_VERSION_CODE

if (is_compat(task)) {
// Translate 32bit syscalls to 64bit syscalls so we can send to the correct handler
Expand Down Expand Up @@ -1492,36 +1463,15 @@ struct bpf_raw_tracepoint_args *ctx
return 0;
}

struct trace_event_raw_sys_exit {
unsigned long long unused;
long int id;
long int ret;
};

// include/trace/events/syscalls.h:
// TP_PROTO(struct pt_regs *regs, long ret)
SEC("raw_tracepoint/sys_exit")
int tracepoint__raw_syscalls__sys_exit(
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
struct trace_event_raw_sys_exit *args
#else
struct bpf_raw_tracepoint_args *ctx
#endif
)
int tracepoint__raw_syscalls__sys_exit(struct bpf_raw_tracepoint_args *ctx)
{
int id;
long ret;
long ret = ctx->args[1];
struct task_struct *task = (struct task_struct *)bpf_get_current_task();

#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
void *ctx = args;
id = args->id;
ret = args->ret;
#else
struct pt_regs *regs = (struct pt_regs*)ctx->args[0];
id = READ_KERN(regs->orig_ax);
ret = ctx->args[1];
#endif
int id = READ_KERN(regs->orig_ax);

if (is_compat(task)) {
// Translate 32bit syscalls to 64bit syscalls so we can send to the correct handler
Expand Down
26 changes: 4 additions & 22 deletions tracee-ebpf/tracee/tracee.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ func UnameRelease() string {
return ver
}

func supportRawTP() (bool, error) {
func kernelIsAtLeast(verMajor, verMinor int) (bool, error) {
ver := UnameRelease()
if ver == "" {
return false, fmt.Errorf("could not determine current release")
Expand All @@ -421,7 +421,7 @@ func supportRawTP() (bool, error) {
if err != nil {
return false, fmt.Errorf("invalid minor number: %s", verSplit[1])
}
if ((major == 4) && (minor >= 17)) || (major > 4) {
if ((major == verMajor) && (minor >= verMinor)) || (major > verMajor) {
return true, nil
}
return false, nil
Expand Down Expand Up @@ -762,11 +762,6 @@ func (t *Tracee) initBPF(bpfObjectPath string) error {
return err
}

supportRawTracepoints, err := supportRawTP()
if err != nil {
return fmt.Errorf("failed to find kernel version: %v", err)
}

// BPFLoadObject() automatically loads ALL BPF programs according to their section type, unless set otherwise
// For every BPF program, we need to make sure that:
// 1. We disable autoload if the program is not required by any event and is not essential
Expand All @@ -788,13 +783,6 @@ func (t *Tracee) initBPF(bpfObjectPath string) error {
}
continue
}
// As kernels < 4.17 don't support raw tracepoints, set these program types to "regular" tracepoint
if !supportRawTracepoints && (prog.GetType() == bpf.BPFProgTypeRawTracepoint) {
err = prog.SetTracepoint()
if err != nil {
return err
}
}
}
}

Expand Down Expand Up @@ -822,17 +810,11 @@ func (t *Tracee) initBPF(bpfObjectPath string) error {
if err != nil {
return fmt.Errorf("error getting program %s: %v", probe.fn, err)
}
if probe.attach == rawTracepoint && !supportRawTracepoints {
// We fallback to regular tracepoint in case kernel doesn't support raw tracepoints (< 4.17)
probe.attach = tracepoint
}
switch probe.attach {
case kprobe:
// todo: after updating minimal kernel version to 4.18, use without legacy
_, err = prog.AttachKprobeLegacy(probe.event)
_, err = prog.AttachKprobe(probe.event)
case kretprobe:
// todo: after updating minimal kernel version to 4.18, use without legacy
_, err = prog.AttachKretprobeLegacy(probe.event)
_, err = prog.AttachKretprobe(probe.event)
case tracepoint:
_, err = prog.AttachTracepoint(probe.event)
case rawTracepoint:
Expand Down

0 comments on commit 59312a1

Please sign in to comment.