From ad333968218d15aec521fd4169dc2379d1ba8350 Mon Sep 17 00:00:00 2001 From: David Windsor Date: Thu, 18 Jul 2024 10:24:30 -0400 Subject: [PATCH] tetragon: add c data types for struct dentry Signed-off-by: David Windsor --- bpf/process/bpf_process_event.h | 35 +++++++++++++++++++++++++++++++++ bpf/process/types/basic.h | 16 +++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/bpf/process/bpf_process_event.h b/bpf/process/bpf_process_event.h index 501137c646d..67bf066584b 100644 --- a/bpf/process/bpf_process_event.h +++ b/bpf/process/bpf_process_event.h @@ -8,6 +8,7 @@ #include "bpf_cgroup.h" #include "bpf_cred.h" +#include "bpf_tracing.h" #define ENAMETOOLONG 36 /* File name too long */ @@ -363,6 +364,40 @@ d_path_local(const struct path *path, int *buflen, int *error) return buffer; } +FUNC_INLINE char *path_from_dentry(struct dentry *dentry, char *buf, int *buflen) +{ + if (d_unlinked(dentry)) { + int error = prepend(&buf, buflen, " (deleted)", 10); + + if (error) // will never happen as prepend will never return a value != 0 + return NULL; + } + + // Construct struct path element with task->nsproxy->mnt_ns->root + struct task_struct *task; + struct nsproxy *ns; + struct mnt_namespace *mnt_ns; + struct vfsmount *root; + + task = (struct task_struct *)get_current_task(); + probe_read(&ns, sizeof(ns), _(&task->nsproxy)); + probe_read(&mnt_ns, sizeof(mnt_ns), _(&ns->mnt_ns)); + probe_read(&root, sizeof(root), _(&mnt_ns->root)); + + struct path target = { + .mnt = root, + .dentry = dentry + }; + + int flags; + + buf = d_path_local(&target, buflen, &flags); + if (!buf) + return NULL; + + return buf; +} + FUNC_INLINE __u32 getcwd(struct msg_process *curr, __u32 offset, __u32 proc_pid) { diff --git a/bpf/process/types/basic.h b/bpf/process/types/basic.h index 74a0d44c849..1080e6bf0d5 100644 --- a/bpf/process/types/basic.h +++ b/bpf/process/types/basic.h @@ -80,6 +80,8 @@ enum { net_dev_ty = 39, + dentry_type = 40, + nop_s64_ty = -10, nop_u64_ty = -11, nop_u32_ty = -12, @@ -221,6 +223,10 @@ struct msg_linux_binprm { char path[MAX_STRING]; } __attribute__((packed)); +struct msg_dentry { + char name[MAX_STRING]; +} __attribute__((packed)); + #ifdef __MULTI_KPROBE FUNC_INLINE __u32 get_index(void *ctx) { @@ -1509,6 +1515,8 @@ FUNC_INLINE size_t type_to_min_size(int type, int argm) return sizeof(struct msg_linux_binprm); case net_dev_ty: return IFNAMSIZ; + case dentry_type: + return sizeof(struct msg_dentry); // nop or something else we do not process here default: return 0; @@ -2480,6 +2488,14 @@ read_call_arg(void *ctx, struct msg_generic_kprobe *e, int index, int type, path_arg = _(&file->f_path); goto do_copy_path; } break; + case dentry_type: { + struct dentry *dentry = (struct dentry *)arg; + char pathbuf[MAX_STRING]; + int len = 0; + char *path = path_from_dentry(dentry, pathbuf, &len); + + size = copy_strings(args, path, MAX_STRING); + }; break; #endif case filename_ty: { struct filename *file;