From c0b0f1d6c5bdeff73e7e84dc799c4009f18608c4 Mon Sep 17 00:00:00 2001 From: Nicholas Berlin Date: Tue, 5 Nov 2024 14:21:28 -0500 Subject: [PATCH 1/3] Use bpf_ktime_get_boot_ns instead bpf_ktime_get_ns does not include suspension time, but we would like ts to represent real world time. Switching the helper function achieves that. The helper was introduced in 5.8 which is earlier than our current support range, 5.10 --- GPL/Events/File/Probe.bpf.c | 8 ++++---- GPL/Events/Network/Probe.bpf.c | 2 +- GPL/Events/Process/Probe.bpf.c | 22 +++++++++++----------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/GPL/Events/File/Probe.bpf.c b/GPL/Events/File/Probe.bpf.c index 7beb4d66..556cf532 100644 --- a/GPL/Events/File/Probe.bpf.c +++ b/GPL/Events/File/Probe.bpf.c @@ -123,7 +123,7 @@ static int vfs_unlink__exit(int ret) } event->hdr.type = EBPF_EVENT_FILE_DELETE; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); ebpf_pid_info__fill(&event->pids, task); ebpf_cred_info__fill(&event->creds, task); @@ -228,7 +228,7 @@ static void prepare_and_send_file_event(struct file *f, return; event->hdr.type = type; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); struct task_struct *task = (struct task_struct *)bpf_get_current_task(); struct path p = BPF_CORE_READ(f, f_path); @@ -483,7 +483,7 @@ static int vfs_rename__exit(int ret) struct dentry *de = (struct dentry *)state->rename.de; event->hdr.type = EBPF_EVENT_FILE_RENAME; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); ebpf_pid_info__fill(&event->pids, task); ebpf_cred_info__fill(&event->creds, task); event->mntns = mntns(task); @@ -551,7 +551,7 @@ static void file_modify_event__emit(enum ebpf_file_change_type typ, struct path } event->hdr.type = EBPF_EVENT_FILE_MODIFY; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); event->change_type = typ; ebpf_pid_info__fill(&event->pids, task); ebpf_cred_info__fill(&event->creds, task); diff --git a/GPL/Events/Network/Probe.bpf.c b/GPL/Events/Network/Probe.bpf.c index dedb11af..f0f151f4 100644 --- a/GPL/Events/Network/Probe.bpf.c +++ b/GPL/Events/Network/Probe.bpf.c @@ -121,7 +121,7 @@ static int udp_skb_handle(struct sk_buff *skb, enum ebpf_net_udp_info evt_type) struct task_struct *task = (struct task_struct *)bpf_get_current_task(); ebpf_pid_info__fill(&event->pids, task); bpf_get_current_comm(event->comm, TASK_COMM_LEN); - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); // constrain the read size to make the verifier happy // see skb_headlen() in skbuff.h diff --git a/GPL/Events/Process/Probe.bpf.c b/GPL/Events/Process/Probe.bpf.c index ef509577..5da18756 100644 --- a/GPL/Events/Process/Probe.bpf.c +++ b/GPL/Events/Process/Probe.bpf.c @@ -53,7 +53,7 @@ int BPF_PROG(sched_process_fork, const struct task_struct *parent, const struct goto out; event->hdr.type = EBPF_EVENT_PROCESS_FORK; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); ebpf_pid_info__fill(&event->parent_pids, parent); ebpf_pid_info__fill(&event->child_pids, child); ebpf_cred_info__fill(&event->creds, parent); @@ -103,7 +103,7 @@ int BPF_PROG(sched_process_exec, goto out; event->hdr.type = EBPF_EVENT_PROCESS_EXEC; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); ebpf_pid_info__fill(&event->pids, task); ebpf_cred_info__fill(&event->creds, task); @@ -199,7 +199,7 @@ static int taskstats_exit__enter(const struct task_struct *task, int group_dead) goto out; event->hdr.type = EBPF_EVENT_PROCESS_EXIT; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); // The exit _status_ is stored in the second byte of task->exit_code int exit_code = BPF_CORE_READ(task, exit_code); @@ -255,7 +255,7 @@ int tracepoint_syscalls_sys_exit_setsid(struct syscall_trace_exit *args) goto out; event->hdr.type = EBPF_EVENT_PROCESS_SETSID; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); ebpf_pid_info__fill(&event->pids, task); @@ -281,7 +281,7 @@ int BPF_PROG(module_load, struct module *mod) goto out; event->hdr.type = EBPF_EVENT_PROCESS_LOAD_MODULE; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); ebpf_pid_info__fill(&event->pids, task); @@ -351,7 +351,7 @@ int BPF_KPROBE(kprobe__ptrace_attach, goto out; event->hdr.type = EBPF_EVENT_PROCESS_PTRACE; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); ebpf_pid_info__fill(&event->pids, task); @@ -391,7 +391,7 @@ int tracepoint_syscalls_sys_enter_shmget(struct syscall_trace_enter *ctx) goto out; event->hdr.type = EBPF_EVENT_PROCESS_SHMGET; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); ebpf_pid_info__fill(&event->pids, task); event->key = ex_args->key; @@ -431,7 +431,7 @@ int tracepoint_syscalls_sys_enter_memfd_create(struct syscall_trace_enter *ctx) goto out; event->hdr.type = EBPF_EVENT_PROCESS_MEMFD_CREATE; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); event->flags = ex_args->flags; ebpf_pid_info__fill(&event->pids, task); @@ -473,7 +473,7 @@ static int commit_creds__enter(struct cred *new) goto out; event->hdr.type = EBPF_EVENT_PROCESS_SETUID; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); ebpf_pid_info__fill(&event->pids, task); @@ -498,7 +498,7 @@ static int commit_creds__enter(struct cred *new) goto out; event->hdr.type = EBPF_EVENT_PROCESS_SETGID; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); ebpf_pid_info__fill(&event->pids, task); @@ -543,7 +543,7 @@ static int output_tty_event(struct ebpf_tty_dev *slave, const void *base, size_t task = (struct task_struct *)bpf_get_current_task(); event->hdr.type = EBPF_EVENT_PROCESS_TTY_WRITE; - event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts = bpf_ktime_get_boot_ns(); u64 len_cap = base_len > TTY_OUT_MAX ? TTY_OUT_MAX : base_len; event->tty_out_truncated = base_len > TTY_OUT_MAX ? base_len - TTY_OUT_MAX : 0; event->tty = *slave; From 2a93bf7ddb3703115d102c7bb441528b44996ea4 Mon Sep 17 00:00:00 2001 From: Nicholas Berlin Date: Wed, 6 Nov 2024 12:49:49 -0500 Subject: [PATCH 2/3] Add ts_boot Add a new event header member, ts_boot, and conditionally set it with bpf_ktime_get_boot_ns() based on the helper's existence --- GPL/Events/EbpfEventProto.h | 1 + GPL/Events/File/Probe.bpf.c | 16 +++++++---- GPL/Events/Helpers.h | 8 ++++++ GPL/Events/Network/Probe.bpf.c | 3 +- GPL/Events/Process/Probe.bpf.c | 52 ++++++++++++++++++++-------------- 5 files changed, 52 insertions(+), 28 deletions(-) diff --git a/GPL/Events/EbpfEventProto.h b/GPL/Events/EbpfEventProto.h index 0277d72f..da57b426 100644 --- a/GPL/Events/EbpfEventProto.h +++ b/GPL/Events/EbpfEventProto.h @@ -49,6 +49,7 @@ enum ebpf_event_type { struct ebpf_event_header { uint64_t ts; + uint64_t ts_boot; uint64_t type; } __attribute__((packed)); diff --git a/GPL/Events/File/Probe.bpf.c b/GPL/Events/File/Probe.bpf.c index 556cf532..4ed6ed35 100644 --- a/GPL/Events/File/Probe.bpf.c +++ b/GPL/Events/File/Probe.bpf.c @@ -123,7 +123,8 @@ static int vfs_unlink__exit(int ret) } event->hdr.type = EBPF_EVENT_FILE_DELETE; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->pids, task); ebpf_cred_info__fill(&event->creds, task); @@ -227,8 +228,9 @@ static void prepare_and_send_file_event(struct file *f, if (!event) return; - event->hdr.type = type; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = type; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); struct task_struct *task = (struct task_struct *)bpf_get_current_task(); struct path p = BPF_CORE_READ(f, f_path); @@ -482,8 +484,9 @@ static int vfs_rename__exit(int ret) // NOTE: this temp variable is necessary to keep the verifier happy struct dentry *de = (struct dentry *)state->rename.de; - event->hdr.type = EBPF_EVENT_FILE_RENAME; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = EBPF_EVENT_FILE_RENAME; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->pids, task); ebpf_cred_info__fill(&event->creds, task); event->mntns = mntns(task); @@ -551,7 +554,8 @@ static void file_modify_event__emit(enum ebpf_file_change_type typ, struct path } event->hdr.type = EBPF_EVENT_FILE_MODIFY; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); event->change_type = typ; ebpf_pid_info__fill(&event->pids, task); ebpf_cred_info__fill(&event->creds, task); diff --git a/GPL/Events/Helpers.h b/GPL/Events/Helpers.h index f9277f14..c8c4a383 100644 --- a/GPL/Events/Helpers.h +++ b/GPL/Events/Helpers.h @@ -367,4 +367,12 @@ static int is_equal_prefix(const char *str1, const char *str2, int len) return !strncmp(str1, str2, len); } +static u64 bpf_ktime_get_boot_ns_helper() +{ + if (bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_ktime_get_boot_ns)) + return bpf_ktime_get_boot_ns(); + else + return 0; +} + #endif // EBPF_EVENTPROBE_HELPERS_H diff --git a/GPL/Events/Network/Probe.bpf.c b/GPL/Events/Network/Probe.bpf.c index f0f151f4..c46401bb 100644 --- a/GPL/Events/Network/Probe.bpf.c +++ b/GPL/Events/Network/Probe.bpf.c @@ -121,7 +121,8 @@ static int udp_skb_handle(struct sk_buff *skb, enum ebpf_net_udp_info evt_type) struct task_struct *task = (struct task_struct *)bpf_get_current_task(); ebpf_pid_info__fill(&event->pids, task); bpf_get_current_comm(event->comm, TASK_COMM_LEN); - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); // constrain the read size to make the verifier happy // see skb_headlen() in skbuff.h diff --git a/GPL/Events/Process/Probe.bpf.c b/GPL/Events/Process/Probe.bpf.c index 5da18756..e802464f 100644 --- a/GPL/Events/Process/Probe.bpf.c +++ b/GPL/Events/Process/Probe.bpf.c @@ -53,7 +53,8 @@ int BPF_PROG(sched_process_fork, const struct task_struct *parent, const struct goto out; event->hdr.type = EBPF_EVENT_PROCESS_FORK; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->parent_pids, parent); ebpf_pid_info__fill(&event->child_pids, child); ebpf_cred_info__fill(&event->creds, parent); @@ -102,8 +103,9 @@ int BPF_PROG(sched_process_exec, if (!event) goto out; - event->hdr.type = EBPF_EVENT_PROCESS_EXEC; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = EBPF_EVENT_PROCESS_EXEC; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->pids, task); ebpf_cred_info__fill(&event->creds, task); @@ -198,8 +200,9 @@ static int taskstats_exit__enter(const struct task_struct *task, int group_dead) if (!event) goto out; - event->hdr.type = EBPF_EVENT_PROCESS_EXIT; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = EBPF_EVENT_PROCESS_EXIT; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); // The exit _status_ is stored in the second byte of task->exit_code int exit_code = BPF_CORE_READ(task, exit_code); @@ -254,8 +257,9 @@ int tracepoint_syscalls_sys_exit_setsid(struct syscall_trace_exit *args) if (!event) goto out; - event->hdr.type = EBPF_EVENT_PROCESS_SETSID; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = EBPF_EVENT_PROCESS_SETSID; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->pids, task); @@ -280,8 +284,9 @@ int BPF_PROG(module_load, struct module *mod) if (!event) goto out; - event->hdr.type = EBPF_EVENT_PROCESS_LOAD_MODULE; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = EBPF_EVENT_PROCESS_LOAD_MODULE; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->pids, task); @@ -350,8 +355,9 @@ int BPF_KPROBE(kprobe__ptrace_attach, if (!event) goto out; - event->hdr.type = EBPF_EVENT_PROCESS_PTRACE; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = EBPF_EVENT_PROCESS_PTRACE; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->pids, task); @@ -390,8 +396,9 @@ int tracepoint_syscalls_sys_enter_shmget(struct syscall_trace_enter *ctx) if (!event) goto out; - event->hdr.type = EBPF_EVENT_PROCESS_SHMGET; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = EBPF_EVENT_PROCESS_SHMGET; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->pids, task); event->key = ex_args->key; @@ -430,8 +437,9 @@ int tracepoint_syscalls_sys_enter_memfd_create(struct syscall_trace_enter *ctx) if (!event) goto out; - event->hdr.type = EBPF_EVENT_PROCESS_MEMFD_CREATE; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = EBPF_EVENT_PROCESS_MEMFD_CREATE; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); event->flags = ex_args->flags; ebpf_pid_info__fill(&event->pids, task); @@ -472,8 +480,9 @@ static int commit_creds__enter(struct cred *new) if (!event) goto out; - event->hdr.type = EBPF_EVENT_PROCESS_SETUID; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = EBPF_EVENT_PROCESS_SETUID; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->pids, task); @@ -497,8 +506,9 @@ static int commit_creds__enter(struct cred *new) if (!event) goto out; - event->hdr.type = EBPF_EVENT_PROCESS_SETGID; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.type = EBPF_EVENT_PROCESS_SETGID; + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->pids, task); @@ -543,7 +553,8 @@ static int output_tty_event(struct ebpf_tty_dev *slave, const void *base, size_t task = (struct task_struct *)bpf_get_current_task(); event->hdr.type = EBPF_EVENT_PROCESS_TTY_WRITE; - event->hdr.ts = bpf_ktime_get_boot_ns(); + event->hdr.ts = bpf_ktime_get_ns(); + event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); u64 len_cap = base_len > TTY_OUT_MAX ? TTY_OUT_MAX : base_len; event->tty_out_truncated = base_len > TTY_OUT_MAX ? base_len - TTY_OUT_MAX : 0; event->tty = *slave; @@ -610,7 +621,6 @@ static int tty_write__enter(struct kiocb *iocb, struct iov_iter *from) iov = BPF_CORE_READ(from, iov); else goto out; - u64 nr_segs = BPF_CORE_READ(from, nr_segs); nr_segs = nr_segs > MAX_NR_SEGS ? MAX_NR_SEGS : nr_segs; From e608192d543720e82be943f1d3dbd00a7742a98b Mon Sep 17 00:00:00 2001 From: Nicholas Berlin Date: Wed, 6 Nov 2024 12:53:33 -0500 Subject: [PATCH 3/3] Code formatting --- GPL/Events/File/Probe.bpf.c | 2 +- GPL/Events/Process/Probe.bpf.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GPL/Events/File/Probe.bpf.c b/GPL/Events/File/Probe.bpf.c index 4ed6ed35..4053a89f 100644 --- a/GPL/Events/File/Probe.bpf.c +++ b/GPL/Events/File/Probe.bpf.c @@ -122,7 +122,7 @@ static int vfs_unlink__exit(int ret) goto out; } - event->hdr.type = EBPF_EVENT_FILE_DELETE; + event->hdr.type = EBPF_EVENT_FILE_DELETE; event->hdr.ts = bpf_ktime_get_ns(); event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->pids, task); diff --git a/GPL/Events/Process/Probe.bpf.c b/GPL/Events/Process/Probe.bpf.c index e802464f..c49b71c5 100644 --- a/GPL/Events/Process/Probe.bpf.c +++ b/GPL/Events/Process/Probe.bpf.c @@ -52,7 +52,7 @@ int BPF_PROG(sched_process_fork, const struct task_struct *parent, const struct if (!event) goto out; - event->hdr.type = EBPF_EVENT_PROCESS_FORK; + event->hdr.type = EBPF_EVENT_PROCESS_FORK; event->hdr.ts = bpf_ktime_get_ns(); event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); ebpf_pid_info__fill(&event->parent_pids, parent); @@ -440,7 +440,7 @@ int tracepoint_syscalls_sys_enter_memfd_create(struct syscall_trace_enter *ctx) event->hdr.type = EBPF_EVENT_PROCESS_MEMFD_CREATE; event->hdr.ts = bpf_ktime_get_ns(); event->hdr.ts_boot = bpf_ktime_get_boot_ns_helper(); - event->flags = ex_args->flags; + event->flags = ex_args->flags; ebpf_pid_info__fill(&event->pids, task);