From 1f10fe49e2e36af908e1c9093c6ae7b8faad433a Mon Sep 17 00:00:00 2001 From: Eddy Duer Date: Wed, 7 Aug 2024 14:26:45 +0300 Subject: [PATCH 1/7] Overlay FS: Add fields proc.is_exe_lower_layer, fd.is_upper_layer and fd.is_lower_layer Signed-off-by: Eddy Duer --- driver/SCHEMA_VERSION | 2 +- driver/bpf/filler_helpers.h | 9 +- driver/bpf/fillers.h | 257 +++++++++++++----- driver/event_table.c | 12 +- driver/flags_table.c | 9 +- .../helpers/extract/extract_from_kernel.h | 58 ++-- .../attached/events/sched_process_exec.bpf.c | 8 +- .../syscall_dispatched_events/creat.bpf.c | 14 +- .../syscall_dispatched_events/execve.bpf.c | 9 +- .../syscall_dispatched_events/execveat.bpf.c | 9 +- .../syscall_dispatched_events/open.bpf.c | 15 +- .../open_by_handle_at.bpf.c | 15 +- .../syscall_dispatched_events/openat.bpf.c | 15 +- .../syscall_dispatched_events/openat2.bpf.c | 15 +- driver/ppm_events_public.h | 14 + driver/ppm_fillers.c | 186 ++++++++++--- userspace/libscap/scap.h | 1 + userspace/libsinsp/fdinfo.h | 22 ++ userspace/libsinsp/parsers.cpp | 34 +++ userspace/libsinsp/sinsp_filtercheck_fd.cpp | 24 ++ userspace/libsinsp/sinsp_filtercheck_fd.h | 2 + .../libsinsp/sinsp_filtercheck_thread.cpp | 4 + userspace/libsinsp/sinsp_filtercheck_thread.h | 1 + userspace/libsinsp/test/state.ut.cpp | 2 +- userspace/libsinsp/threadinfo.cpp | 3 + userspace/libsinsp/threadinfo.h | 1 + 26 files changed, 593 insertions(+), 148 deletions(-) diff --git a/driver/SCHEMA_VERSION b/driver/SCHEMA_VERSION index 8392a795a9..f48f82fa2c 100644 --- a/driver/SCHEMA_VERSION +++ b/driver/SCHEMA_VERSION @@ -1 +1 @@ -2.21.2 +2.22.0 diff --git a/driver/bpf/filler_helpers.h b/driver/bpf/filler_helpers.h index a2b7115bc8..01c3cd8ce7 100644 --- a/driver/bpf/filler_helpers.h +++ b/driver/bpf/filler_helpers.h @@ -280,21 +280,20 @@ static __always_inline unsigned long bpf_encode_dev(dev_t dev) return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12); } -static __always_inline void bpf_get_fd_dev_ino(int fd, unsigned long *dev, unsigned long *ino) +static __always_inline void bpf_get_fd_dev_ino_file(int fd, unsigned long *dev, unsigned long *ino, struct file **file) { struct super_block *sb; struct inode *inode; - struct file *file; dev_t kdev; if (fd < 0) return; - file = bpf_fget(fd); - if (!file) + *file = bpf_fget(fd); + if (!*file) return; - inode = _READ(file->f_inode); + inode = _READ((*file)->f_inode); if (!inode) return; diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index 8c96a5da59..73e895138f 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -89,6 +89,45 @@ static __always_inline int bpf_##x(void *ctx) \ \ static __always_inline int __bpf_##x(struct filler_data *data) \ +static __always_inline struct inode *get_file_inode(struct file *file) +{ + if (file) { + return _READ(file->f_inode); + } + return NULL; +} + +static __always_inline enum ppm_overlay get_overlay_layer(struct file *file) +{ + struct dentry* dentry = NULL; + bpf_probe_read_kernel(&dentry, sizeof(dentry), &file->f_path.dentry); + struct super_block* sb = (struct super_block*)_READ(dentry->d_sb); + unsigned long sb_magic = _READ(sb->s_magic); + + if(sb_magic != PPM_OVERLAYFS_SUPER_MAGIC) + { + return PPM_NOT_OVERLAY_FS; + } + + char *vfs_inode = (char *)_READ(dentry->d_inode); + struct dentry *upper_dentry = NULL; + bpf_probe_read_kernel(&upper_dentry, sizeof(upper_dentry), (char *)vfs_inode + sizeof(struct inode)); + if(!upper_dentry) + { + return PPM_OVERLAY_LOWER; + } + + struct inode *upper_ino = _READ(upper_dentry->d_inode); + if(_READ(upper_ino->i_ino) != 0) + { + return PPM_OVERLAY_UPPER; + } + else + { + return PPM_OVERLAY_LOWER; + } +} + FILLER_RAW(terminate_filler) { struct scap_bpf_per_cpu_state *state; @@ -364,6 +403,8 @@ FILLER(sys_open_x, true) unsigned long ino = 0; long retval; int res; + struct file *file = NULL; + unsigned int fd_flags = 0; /* Parameter 1: ret (type: PT_FD) */ retval = bpf_syscall_get_retval(data->ctx); @@ -389,14 +430,30 @@ FILLER(sys_open_x, true) res = bpf_push_u32_to_ring(data, mode); CHECK_RES(res); - bpf_get_fd_dev_ino(retval, &dev, &ino); + bpf_get_fd_dev_ino_file(retval, &dev, &ino, &file); /* Parameter 5: dev (type: PT_UINT32) */ res = bpf_push_u32_to_ring(data, (uint32_t)dev); CHECK_RES(res); /* Parameter 6: ino (type: PT_UINT64) */ - return bpf_push_u64_to_ring(data, (uint64_t)ino);; + res = bpf_push_u64_to_ring(data, (uint64_t)ino); + CHECK_RES(res); + + /* Parameter 7: fd_flags (type: PT_UINT32) */ + if (likely(file)) + { + enum ppm_overlay ol = get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + } + return bpf_push_u32_to_ring(data, (uint32_t)fd_flags); } FILLER(sys_read_e, true) @@ -2162,14 +2219,6 @@ static __always_inline struct file *get_exe_file(struct task_struct *task) return NULL; } -static __always_inline struct inode *get_file_inode(struct file *file) -{ - if (file) { - return _READ(file->f_inode); - } - return NULL; -} - /* * Detect whether the file being referenced is an anonymous file created using memfd_create() * and is being executed by referencing its file descriptor (fd). This type of file does not @@ -2314,30 +2363,6 @@ static __always_inline bool get_exe_writable(struct inode *inode, struct cred *c return false; } -static __always_inline bool get_exe_upper_layer(struct file *file) -{ - struct dentry* dentry = NULL; - bpf_probe_read_kernel(&dentry, sizeof(dentry), &file->f_path.dentry); - struct super_block* sb = (struct super_block*)_READ(dentry->d_sb); - unsigned long sb_magic = _READ(sb->s_magic); - - if(sb_magic != PPM_OVERLAYFS_SUPER_MAGIC) - { - return false; - } - - char *vfs_inode = (char *)_READ(dentry->d_inode); - struct dentry *upper_dentry = NULL; - bpf_probe_read_kernel(&upper_dentry, sizeof(upper_dentry), (char *)vfs_inode + sizeof(struct inode)); - if(!upper_dentry) - { - return false; - } - - struct inode *upper_ino = _READ(upper_dentry->d_inode); - return _READ(upper_ino->i_ino) != 0; -} - FILLER(proc_startupdate, true) { struct task_struct *real_parent; @@ -2863,16 +2888,24 @@ FILLER(execve_extra_tail_1, true) } /* - * exe_upper_layer + * exe_upper_layer/exe_lower_layer and exe_from_memfd */ - if(exe_file && get_exe_upper_layer(exe_file)) + if(exe_file) { - flags |= PPM_EXE_UPPER_LAYER; - } + enum ppm_overlay exe_layer = get_overlay_layer(exe_file); + if (exe_layer == PPM_OVERLAY_UPPER) + { + flags |= PPM_EXE_UPPER_LAYER; + } + else if (exe_layer == PPM_OVERLAY_LOWER) + { + flags |= PPM_EXE_LOWER_LAYER; + } - if(exe_file && get_exe_from_memfd(exe_file)) - { - flags |= PPM_EXE_FROM_MEMFD; + if(get_exe_from_memfd(exe_file)) + { + flags |= PPM_EXE_FROM_MEMFD; + } } /* Parameter 20: flags (type: PT_FLAGS32) */ @@ -3181,6 +3214,8 @@ FILLER(sys_openat_x, true) long retval; int32_t fd; int res; + struct file *file = NULL; + unsigned int fd_flags = 0; retval = bpf_syscall_get_retval(data->ctx); res = bpf_push_s64_to_ring(data, retval); @@ -3222,7 +3257,7 @@ FILLER(sys_openat_x, true) res = bpf_push_u32_to_ring(data, mode); CHECK_RES(res); - bpf_get_fd_dev_ino(retval, &dev, &ino); + bpf_get_fd_dev_ino_file(retval, &dev, &ino, &file); /* * Device @@ -3233,7 +3268,25 @@ FILLER(sys_openat_x, true) /* * Ino */ - return bpf_push_u64_to_ring(data, ino); + res = bpf_push_u64_to_ring(data, ino); + CHECK_RES(res); + + /* + * fd_flags + */ + if (likely(file)) + { + enum ppm_overlay ol = get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + } + return bpf_push_u32_to_ring(data, (uint32_t)fd_flags); } FILLER(sys_openat2_e, true) @@ -3314,6 +3367,8 @@ FILLER(sys_openat2_x, true) long retval; int32_t fd; int res; + struct file *file = NULL; + unsigned int fd_flags = 0; #ifdef __NR_openat2 struct open_how how; #endif @@ -3379,7 +3434,7 @@ FILLER(sys_openat2_x, true) res = bpf_push_u32_to_ring(data, resolve); CHECK_RES(res); - bpf_get_fd_dev_ino(retval, &dev, &ino); + bpf_get_fd_dev_ino_file(retval, &dev, &ino, &file); /* * dev @@ -3390,7 +3445,25 @@ FILLER(sys_openat2_x, true) /* * ino */ - return bpf_push_u64_to_ring(data, ino); + res = bpf_push_u64_to_ring(data, ino); + CHECK_RES(res); + + /* + * fd_flags + */ + if (likely(file)) + { + enum ppm_overlay ol = get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + } + return bpf_push_u32_to_ring(data, (uint32_t)fd_flags); } FILLER(sys_open_by_handle_at_x, true) @@ -3436,13 +3509,24 @@ FILLER(sys_open_by_handle_at_x, true) CHECK_RES(res); /* Parameter 6: ino (type: PT_UINT64) */ - return bpf_push_u64_to_ring(data, 0); + res = bpf_push_u64_to_ring(data, 0); + CHECK_RES(res); + + /* Parameter 7: fd_flags (type: PT_UINT32) */ + return bpf_push_u32_to_ring(data, 0); + } FILLER(open_by_handle_at_x_extra_tail_1, true) { long retval = bpf_syscall_get_retval(data->ctx); - struct file *f = bpf_fget(retval); + struct file *f = NULL; + unsigned long dev = 0; + unsigned long ino = 0; + unsigned int fd_flags = 0; + + bpf_get_fd_dev_ino_file(retval, &dev, &ino, &f); + if(f == NULL) { /* In theory here we should send an empty param but we are experimenting some issues @@ -3459,17 +3543,28 @@ FILLER(open_by_handle_at_x_extra_tail_1, true) char* filepath = bpf_d_path_approx(data, &(f->f_path)); int res = bpf_val_to_ring_mem(data,(unsigned long)filepath, KERNEL); - unsigned long dev = 0; - unsigned long ino = 0; - - bpf_get_fd_dev_ino(retval, &dev, &ino); - /* Parameter 5: dev (type: PT_UINT32) */ res = bpf_push_u32_to_ring(data, dev); CHECK_RES(res); /* Parameter 6: ino (type: PT_UINT64) */ - return bpf_push_u64_to_ring(data, ino); + res = bpf_push_u64_to_ring(data, ino); + CHECK_RES(res); + + /* Parameter 7: fd_flags (type: PT_UINT32) */ + if (likely(f)) + { + enum ppm_overlay ol = get_overlay_layer(f); + if (ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + } + return bpf_push_u32_to_ring(data, (uint32_t)fd_flags); } FILLER(sys_io_uring_setup_x, true) @@ -4550,6 +4645,8 @@ FILLER(sys_creat_x, true) unsigned long mode; long retval; int res; + struct file *file = NULL; + unsigned int fd_flags = 0; retval = bpf_syscall_get_retval(data->ctx); res = bpf_push_s64_to_ring(data, retval); @@ -4570,7 +4667,7 @@ FILLER(sys_creat_x, true) res = bpf_push_u32_to_ring(data, mode); CHECK_RES(res); - bpf_get_fd_dev_ino(retval, &dev, &ino); + bpf_get_fd_dev_ino_file(retval, &dev, &ino, &file); /* * Device @@ -4581,7 +4678,25 @@ FILLER(sys_creat_x, true) /* * Ino */ - return bpf_push_u64_to_ring(data, ino); + res = bpf_push_u64_to_ring(data, ino); + CHECK_RES(res); + + /* + * fd_flags + */ + if (likely(file)) + { + enum ppm_overlay ol = get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + } + return bpf_push_u32_to_ring(data, (uint32_t)fd_flags); } FILLER(sys_pipe_x, true) @@ -4609,12 +4724,13 @@ FILLER(sys_pipe_x, true) CHECK_RES(res); unsigned long ino = 0; - /* Not used, we use it just to call `bpf_get_fd_dev_ino` */ + /* Not used, we use it just to call `bpf_get_fd_dev_ino_file` */ unsigned long dev = 0; + struct file *file = NULL; /* On success, pipe returns `0` */ if(retval == 0) { - bpf_get_fd_dev_ino(pipefd[0], &dev, &ino); + bpf_get_fd_dev_ino_file(pipefd[0], &dev, &ino, &file); } /* Parameter 4: ino (type: PT_UINT64) */ @@ -4646,12 +4762,13 @@ FILLER(sys_pipe2_x, true) CHECK_RES(res); unsigned long ino = 0; - /* Not used, we use it just to call `bpf_get_fd_dev_ino` */ + /* Not used, we use it just to call `bpf_get_fd_dev_ino_file` */ unsigned long dev = 0; + struct file *file = NULL; /* On success, pipe returns `0` */ if(retval == 0) { - bpf_get_fd_dev_ino(pipefd[0], &dev, &ino); + bpf_get_fd_dev_ino_file(pipefd[0], &dev, &ino, &file); } /* Parameter 4: ino (type: PT_UINT64) */ @@ -6771,16 +6888,24 @@ FILLER(sched_prog_exec_4, false) } /* - * exe_upper_layer + * exe_upper_layer/exe_lower_layer and exe_from_memfd */ - if (exe_file && get_exe_upper_layer(exe_file)) + if(exe_file) { - flags |= PPM_EXE_UPPER_LAYER; - } + enum ppm_overlay exe_layer = get_overlay_layer(exe_file); + if (exe_layer == PPM_OVERLAY_UPPER) + { + flags |= PPM_EXE_UPPER_LAYER; + } + else if (exe_layer == PPM_OVERLAY_LOWER) + { + flags |= PPM_EXE_LOWER_LAYER; + } - if(exe_file && get_exe_from_memfd(exe_file)) - { - flags |= PPM_EXE_FROM_MEMFD; + if(get_exe_from_memfd(exe_file)) + { + flags |= PPM_EXE_FROM_MEMFD; + } } /* Parameter 20: flags (type: PT_FLAGS32) */ diff --git a/driver/event_table.c b/driver/event_table.c index dda33eb007..272bfc8123 100644 --- a/driver/event_table.c +++ b/driver/event_table.c @@ -53,8 +53,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_GENERIC_E] = {"syscall", EC_OTHER | EC_SYSCALL, EF_NONE, 2, {{"ID", PT_SYSCALLID, PF_DEC}, {"nativeID", PT_UINT16, PF_DEC} } }, [PPME_GENERIC_X] = {"syscall", EC_OTHER | EC_SYSCALL, EF_NONE, 1, {{"ID", PT_SYSCALLID, PF_DEC} } }, [PPME_SYSCALL_OPEN_E] = {"open", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 3, {{"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT} } }, - [PPME_SYSCALL_OPEN_X] = {"open", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, - [PPME_SYSCALL_CLOSE_E] = {"close", EC_IO_OTHER | EC_SYSCALL, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } }, + [PPME_SYSCALL_OPEN_X] = {"open", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 7, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_CLOSE_E] = {"close", EC_IO_OTHER | EC_SYSCALL, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } }, [PPME_SYSCALL_CLOSE_X] = {"close", EC_IO_OTHER | EC_SYSCALL, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_ERRNO, PF_DEC} } }, [PPME_SYSCALL_READ_E] = {"read", EC_IO_READ | EC_SYSCALL, EF_USES_FD | EF_READS_FROM_FD, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_READ_X] = {"read", EC_IO_READ | EC_SYSCALL, EF_USES_FD | EF_READS_FROM_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, @@ -109,8 +108,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_SOCKET_ACCEPT4_E] = {"accept", EC_NET | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 1, {{"flags", PT_INT32, PF_HEX} } }, [PPME_SOCKET_ACCEPT4_X] = {"accept", EC_NET | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 3, {{"fd", PT_FD, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA}, {"queuepct", PT_UINT8, PF_DEC} } }, [PPME_SYSCALL_CREAT_E] = {"creat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 2, {{"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT} } }, - [PPME_SYSCALL_CREAT_X] = {"creat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, - [PPME_SYSCALL_PIPE_E] = {"pipe", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, + [PPME_SYSCALL_CREAT_X] = {"creat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_PIPE_E] = {"pipe", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, [PPME_SYSCALL_PIPE_X] = {"pipe", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"fd1", PT_FD, PF_DEC}, {"fd2", PT_FD, PF_DEC}, {"ino", PT_UINT64, PF_DEC} } }, [PPME_SYSCALL_EVENTFD_E] = {"eventfd", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 2, {{"initval", PT_UINT64, PF_DEC}, {"flags", PT_UINT32, PF_HEX} } }, [PPME_SYSCALL_EVENTFD_X] = {"eventfd", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_FD, PF_DEC} } }, @@ -359,7 +357,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_SYSCALL_MKDIRAT_E] = {"mkdirat", EC_FILE | EC_SYSCALL, EF_NONE, 0}, [PPME_SYSCALL_MKDIRAT_X] = {"mkdirat", EC_FILE | EC_SYSCALL, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"path", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"mode", PT_UINT32, PF_HEX} } }, [PPME_SYSCALL_OPENAT_2_E] = {"openat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(0)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT} } }, - [PPME_SYSCALL_OPENAT_2_X] = {"openat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 7, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, + [PPME_SYSCALL_OPENAT_2_X] = {"openat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 8, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_LINK_2_E] = {"link", EC_FILE | EC_SYSCALL, EF_NONE, 0}, [PPME_SYSCALL_LINK_2_X] = {"link", EC_FILE | EC_SYSCALL, EF_NONE, 3, {{"res", PT_ERRNO, PF_DEC}, {"oldpath", PT_FSPATH, PF_NA}, {"newpath", PT_FSPATH, PF_NA} } }, [PPME_SYSCALL_LINKAT_2_E] = {"linkat", EC_FILE | EC_SYSCALL, EF_NONE, 0}, @@ -379,7 +377,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_CONTAINER_JSON_2_E] = {"container", EC_PROCESS | EC_METAEVENT, EF_MODIFIES_STATE | EF_LARGE_PAYLOAD, 1, {{"json", PT_CHARBUF, PF_NA} } }, /// TODO: do we need SKIPPARSERESET flag? [PPME_CONTAINER_JSON_2_X] = {"NA", EC_UNKNOWN, EF_UNUSED, 0}, [PPME_SYSCALL_OPENAT2_E] = {"openat2", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags} } }, - [PPME_SYSCALL_OPENAT2_X] = {"openat2", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 8, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, + [PPME_SYSCALL_OPENAT2_X] = {"openat2", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 9, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_MPROTECT_E] = {"mprotect", EC_MEMORY | EC_SYSCALL, EF_NONE, 3, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags} } }, [PPME_SYSCALL_MPROTECT_X] = {"mprotect", EC_MEMORY | EC_SYSCALL, EF_NONE, 1, {{"res", PT_ERRNO, PF_DEC} } }, [PPME_SYSCALL_EXECVEAT_E] = {"execveat", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE, 3, {{"dirfd", PT_FD, PF_DEC}, {"pathname", PT_FSRELPATH, PF_NA, DIRFD_PARAM(0)}, {"flags", PT_FLAGS32, PF_HEX, execveat_flags} } }, @@ -389,7 +387,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_SYSCALL_CLONE3_E] = {"clone3", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE, 0}, [PPME_SYSCALL_CLONE3_X] = {"clone3", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE, 21, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"vtid", PT_PID, PF_DEC}, {"vpid", PT_PID, PF_DEC}, {"pidns_init_start_ts", PT_UINT64, PF_DEC} } }, [PPME_SYSCALL_OPEN_BY_HANDLE_AT_E] = {"open_by_handle_at", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, - [PPME_SYSCALL_OPEN_BY_HANDLE_AT_X] = {"open_by_handle_at", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"mountfd", PT_FD, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"path", PT_FSPATH, PF_NA}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, + [PPME_SYSCALL_OPEN_BY_HANDLE_AT_X] = {"open_by_handle_at", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 7, {{"fd", PT_FD, PF_DEC}, {"mountfd", PT_FD, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"path", PT_FSPATH, PF_NA}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_IO_URING_SETUP_E] = {"io_uring_setup", EC_IO_OTHER | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, [PPME_SYSCALL_IO_URING_SETUP_X] = {"io_uring_setup", EC_IO_OTHER | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 8, {{"res", PT_ERRNO, PF_DEC}, {"entries", PT_UINT32, PF_DEC}, {"sq_entries", PT_UINT32, PF_DEC},{"cq_entries", PT_UINT32, PF_DEC},{"flags", PT_FLAGS32, PF_HEX, io_uring_setup_flags},{"sq_thread_cpu", PT_UINT32, PF_DEC}, {"sq_thread_idle", PT_UINT32, PF_DEC},{"features", PT_FLAGS32, PF_HEX, io_uring_setup_feats}}}, [PPME_SYSCALL_IO_URING_ENTER_E] = {"io_uring_enter", EC_IO_OTHER | EC_SYSCALL, EF_NONE, 0}, diff --git a/driver/flags_table.c b/driver/flags_table.c index 67de5c8429..d4b37f4118 100644 --- a/driver/flags_table.c +++ b/driver/flags_table.c @@ -558,6 +558,7 @@ const struct ppm_name_value execve_flags[] = { {"EXE_WRITABLE", PPM_EXE_WRITABLE}, {"EXE_UPPER_LAYER", PPM_EXE_UPPER_LAYER}, {"EXE_FROM_MEMFD", PPM_EXE_FROM_MEMFD}, + {"EXE_LOWER_LAYER", PPM_EXE_LOWER_LAYER}, {0, 0}, }; @@ -769,4 +770,10 @@ const struct ppm_name_value finit_module_flags[] = { {"MODULE_INIT_IGNORE_VERMAGIC", PPM_MODULE_INIT_IGNORE_VERMAGIC}, {"MODULE_INIT_COMPRESSED_FILE", PPM_MODULE_INIT_COMPRESSED_FILE}, {0, 0}, -}; \ No newline at end of file +}; + +const struct ppm_name_value fd_flags[] = { + {"FD_UPPER_LAYER", PPM_FD_UPPER_LAYER}, + {"FD_LOWER_LAYER", PPM_FD_LOWER_LAYER}, + {0, 0}, +}; diff --git a/driver/modern_bpf/helpers/extract/extract_from_kernel.h b/driver/modern_bpf/helpers/extract/extract_from_kernel.h index f8f3380d66..88815abed5 100644 --- a/driver/modern_bpf/helpers/extract/extract_from_kernel.h +++ b/driver/modern_bpf/helpers/extract/extract_from_kernel.h @@ -337,26 +337,6 @@ static __always_inline uint64_t extract__epoch_ns_from_time(struct timespec64 ti return (tv_sec * (uint64_t) 1000000000 + time.tv_nsec); } -/** - * \brief Extract the device number and the inode number from a file descriptor. - * - * @param fd generic file descriptor. - * @param dev pointer to the device number we have to fill. - * @param ino pointer to the inode number we have to fill. - */ -static __always_inline void extract__dev_and_ino_from_fd(int32_t fd, dev_t *dev, uint64_t *ino) -{ - struct file *f = extract__file_struct_from_fd(fd); - if(!f) - { - return; - } - - BPF_CORE_READ_INTO(dev, f, f_inode, i_sb, s_dev); - *dev = encode_dev(*dev); - BPF_CORE_READ_INTO(ino, f, f_inode, i_ino); -} - /** * \brief Extract the file mode created flag from a file descriptor. * @@ -831,14 +811,14 @@ static __always_inline void extract__egid(struct task_struct *task, uint32_t *eg // EXECVE FLAGS EXTRACTION //////////////////////// -static __always_inline bool extract__exe_upper_layer(struct file *file) +static __always_inline enum ppm_overlay extract__overlay_layer(struct file *file) { struct dentry *dentry = (struct dentry *)BPF_CORE_READ(file, f_path.dentry); unsigned long sb_magic = BPF_CORE_READ(dentry, d_sb, s_magic); if(sb_magic != PPM_OVERLAYFS_SUPER_MAGIC) { - return false; + return PPM_NOT_OVERLAY_FS; } char *vfs_inode = (char *)BPF_CORE_READ(dentry, d_inode); @@ -846,20 +826,23 @@ static __always_inline bool extract__exe_upper_layer(struct file *file) unsigned long inode_size = bpf_core_type_size(struct inode); if(!inode_size) { - return false; + return PPM_OVERLAY_LOWER; } struct dentry *upper_dentry = NULL; bpf_probe_read_kernel(&upper_dentry, sizeof(upper_dentry), (char *)vfs_inode + inode_size); if(!upper_dentry) { - return false; + return PPM_OVERLAY_LOWER; } - return BPF_CORE_READ(upper_dentry, d_inode, i_ino) != 0; + if (BPF_CORE_READ(upper_dentry, d_inode, i_ino) != 0) + { + return PPM_OVERLAY_UPPER; + } + return PPM_OVERLAY_LOWER; } - /* * Detect whether the file being referenced is an anonymous file created using memfd_create() * and is being executed by referencing its file descriptor (fd). This type of file does not @@ -914,6 +897,29 @@ static __always_inline bool extract__exe_from_memfd(struct file *file) return true; } +/** + * \brief Extract the device number and the inode number from a file descriptor. + * + * @param fd generic file descriptor. + * @param dev pointer to the device number we have to fill. + * @param ino pointer to the inode number we have to fill. + */ +static __always_inline void extract__dev_ino_and_file_from_fd(int32_t fd, dev_t *dev, uint64_t *ino, enum ppm_overlay *ol) +{ + struct file *f = extract__file_struct_from_fd(fd); + if(!f) + { + return; + } + + struct inode *i = BPF_CORE_READ(f, f_inode); + *ol = extract__overlay_layer(f); + + BPF_CORE_READ_INTO(dev, i, i_sb, s_dev); + *dev = encode_dev(*dev); + BPF_CORE_READ_INTO(ino, i, i_ino); +} + /* log(NGROUPS_MAX) = log(65536) */ #define MAX_GROUP_SEARCH_DEPTH 16 diff --git a/driver/modern_bpf/programs/attached/events/sched_process_exec.bpf.c b/driver/modern_bpf/programs/attached/events/sched_process_exec.bpf.c index cc30218afb..512cc26342 100644 --- a/driver/modern_bpf/programs/attached/events/sched_process_exec.bpf.c +++ b/driver/modern_bpf/programs/attached/events/sched_process_exec.bpf.c @@ -166,14 +166,20 @@ int BPF_PROG(t1_sched_p_exec, struct inode *exe_inode = extract__exe_inode_from_task(task); struct file *exe_file = extract__exe_file_from_task(task); + enum ppm_overlay overlay; if(extract__exe_writable(task, exe_inode)) { flags |= PPM_EXE_WRITABLE; } - if(extract__exe_upper_layer(exe_file)) + overlay = extract__overlay_layer(exe_file); + if(overlay == PPM_OVERLAY_UPPER) { flags |= PPM_EXE_UPPER_LAYER; } + else if (overlay == PPM_OVERLAY_LOWER) + { + flags |= PPM_EXE_LOWER_LAYER; + } if(extract__exe_from_memfd(exe_file)) { flags |= PPM_EXE_FROM_MEMFD; diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c index 35615215da..102e09baeb 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c @@ -74,10 +74,12 @@ int BPF_PROG(creat_x, dev_t dev = 0; uint64_t ino = 0; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; + uint32_t fd_flags = 0; if(ret > 0) { - extract__dev_and_ino_from_fd(ret, &dev, &ino); + extract__dev_ino_and_file_from_fd(ret, &dev, &ino, &ol); } /* Parameter 4: dev (type: PT_UINT32) */ @@ -86,6 +88,16 @@ int BPF_PROG(creat_x, /* Parameter 5: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); + /* Parameter 6: fd_flags (type: PT_UINT32) */ + if(ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if(ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + auxmap__store_u32_param(auxmap, fd_flags); /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execve.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execve.bpf.c index 1b7a31d51b..b09e983189 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execve.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execve.bpf.c @@ -226,14 +226,21 @@ int BPF_PROG(t1_execve_x, struct inode *exe_inode = extract__exe_inode_from_task(task); struct file *exe_file = extract__exe_file_from_task(task); + enum ppm_overlay overlay; + if(extract__exe_writable(task, exe_inode)) { flags |= PPM_EXE_WRITABLE; } - if(extract__exe_upper_layer(exe_file)) + overlay = extract__overlay_layer(exe_file); + if(overlay == PPM_OVERLAY_UPPER) { flags |= PPM_EXE_UPPER_LAYER; } + else if (overlay == PPM_OVERLAY_LOWER) + { + flags |= PPM_EXE_LOWER_LAYER; + } if(extract__exe_from_memfd(exe_file)) { flags |= PPM_EXE_FROM_MEMFD; diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execveat.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execveat.bpf.c index 75f225701e..388661dfd2 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execveat.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execveat.bpf.c @@ -240,14 +240,21 @@ int BPF_PROG(t1_execveat_x, struct inode *exe_inode = extract__exe_inode_from_task(task); struct file *exe_file = extract__exe_file_from_task(task); + enum ppm_overlay overlay; + if(extract__exe_writable(task, exe_inode)) { flags |= PPM_EXE_WRITABLE; } - if(extract__exe_upper_layer(exe_file)) + overlay = extract__overlay_layer(exe_file); + if(overlay == PPM_OVERLAY_UPPER) { flags |= PPM_EXE_UPPER_LAYER; } + else if (overlay == PPM_OVERLAY_LOWER) + { + flags |= PPM_EXE_LOWER_LAYER; + } if(extract__exe_from_memfd(exe_file)) { flags |= PPM_EXE_FROM_MEMFD; diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c index 17a5332288..07cc3517be 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c @@ -85,10 +85,12 @@ int BPF_PROG(open_x, dev_t dev = 0; uint64_t ino = 0; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; + uint32_t fd_flags = 0; if(ret > 0) { - extract__dev_and_ino_from_fd(ret, &dev, &ino); + extract__dev_ino_and_file_from_fd(ret, &dev, &ino, &ol); } /* Parameter 5: dev (type: PT_UINT32) */ @@ -97,6 +99,17 @@ int BPF_PROG(open_x, /* Parameter 6: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); + /* Parameter 7: fd_flags (type: PT_UINT32) */ + if(ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if(ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + auxmap__store_u32_param(auxmap, fd_flags); + /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c index 9ac21a1208..f3945a7e5c 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c @@ -84,6 +84,8 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) { dev_t dev = 0; uint64_t ino = 0; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; + uint32_t fd_flags = 0; struct auxiliary_map *auxmap = auxmap__get(); if(!auxmap) @@ -107,7 +109,7 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) auxmap__store_empty_param(auxmap); } - extract__dev_and_ino_from_fd(ret, &dev, &ino); + extract__dev_ino_and_file_from_fd(ret, &dev, &ino, &ol); } else { @@ -120,6 +122,17 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) /* Parameter 6: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); + /* Parameter 7: fd_flags (type: PT_UINT32) */ + if(ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if(ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + auxmap__store_u32_param(auxmap, fd_flags); + /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c index ce58cb78d9..83bb93fc83 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c @@ -102,10 +102,12 @@ int BPF_PROG(openat_x, dev_t dev = 0; uint64_t ino = 0; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; + uint32_t fd_flags = 0; if(ret > 0) { - extract__dev_and_ino_from_fd(ret, &dev, &ino); + extract__dev_ino_and_file_from_fd(ret, &dev, &ino, &ol); } /* Parameter 6: dev (type: PT_UINT32) */ @@ -114,6 +116,17 @@ int BPF_PROG(openat_x, /* Parameter 7: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); + /* Parameter 8: fd_flags (type: PT_UINT32) */ + if(ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if(ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + auxmap__store_u32_param(auxmap, fd_flags); + /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c index 133beeed3d..6de8c514d6 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c @@ -114,10 +114,12 @@ int BPF_PROG(openat2_x, dev_t dev = 0; uint64_t ino = 0; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; + uint32_t fd_flags = 0; if(ret > 0) { - extract__dev_and_ino_from_fd(ret, &dev, &ino); + extract__dev_ino_and_file_from_fd(ret, &dev, &ino, &ol); } /* Parameter 7: dev (type: PT_UINT32) */ @@ -126,6 +128,17 @@ int BPF_PROG(openat2_x, /* Parameter 8: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); + /* Parameter 9: fd_flags (type: PT_UINT32) */ + if(ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if(ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + auxmap__store_u32_param(auxmap, fd_flags); + /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/ppm_events_public.h b/driver/ppm_events_public.h index 8fa5cbbd73..53f6a0fa03 100644 --- a/driver/ppm_events_public.h +++ b/driver/ppm_events_public.h @@ -633,6 +633,7 @@ or GPL2.txt for full copies of the license. #define PPM_EXE_WRITABLE (1 << 0) #define PPM_EXE_UPPER_LAYER (1 << 1) #define PPM_EXE_FROM_MEMFD (1 << 2) +#define PPM_EXE_LOWER_LAYER (1 << 3) /* * Execveat flags @@ -811,6 +812,12 @@ or GPL2.txt for full copies of the license. #define PPM_DELETE_MODULE_O_TRUNC (1 << 0) #define PPM_DELETE_MODULE_O_NONBLOCK (1 << 1) +/* + * FD flags + */ +#define PPM_FD_UPPER_LAYER (1 << 0) +#define PPM_FD_LOWER_LAYER (1 << 1) + /* * bpf_commands */ @@ -1044,6 +1051,13 @@ enum ppm_capture_category { PPMC_SCHED_PROC_FORK = 6, }; +enum ppm_overlay +{ + PPM_NOT_OVERLAY_FS = 0, + PPM_OVERLAY_UPPER = 1, + PPM_OVERLAY_LOWER = 2, +}; + /** @defgroup etypes Event Types * @{ */ diff --git a/driver/ppm_fillers.c b/driver/ppm_fillers.c index bd250f3ad3..7c63e70284 100644 --- a/driver/ppm_fillers.c +++ b/driver/ppm_fillers.c @@ -65,6 +65,8 @@ struct ovl_entry { #define merge_64(hi, lo) ((((unsigned long long)(hi)) << 32) + ((lo) & 0xffffffffUL)) +static enum ppm_overlay ppm_get_overlay_layer(struct file *file); + static inline struct pid_namespace *pid_ns_for_children(struct task_struct *task) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)) @@ -181,11 +183,10 @@ int f_sys_fstat_e(struct event_filler_arguments *args) return add_sentinel(args); } -static inline void get_fd_dev_ino(int64_t fd, uint32_t* dev, uint64_t* ino) +static inline void get_fd_dev_ino_file(int64_t fd, uint32_t* dev, uint64_t* ino, struct file **file) { struct files_struct *files; struct fdtable *fdt; - struct file *file; struct inode *inode; struct super_block *sb; @@ -201,11 +202,11 @@ static inline void get_fd_dev_ino(int64_t fd, uint32_t* dev, uint64_t* ino) if (unlikely(fd > fdt->max_fds)) goto out_unlock; - file = fdt->fd[fd]; - if (unlikely(!file)) + *file = fdt->fd[fd]; + if (unlikely(!*file)) goto out_unlock; - inode = file_inode(file); + inode = file_inode(*file); if (unlikely(!inode)) goto out_unlock; @@ -297,6 +298,9 @@ int f_sys_open_x(struct event_filler_arguments *args) uint64_t ino = 0; int res; int64_t retval; + struct file *file = NULL; + enum ppm_overlay ol; + int32_t fd_flags = 0; /* * fd @@ -331,7 +335,7 @@ int f_sys_open_x(struct event_filler_arguments *args) res = val_to_ring(args, open_modes_to_scap(flags, modes), 0, false, 0); CHECK_RES(res); - get_fd_dev_ino(retval, &dev, &ino); + get_fd_dev_ino_file(retval, &dev, &ino, &file); /* * dev @@ -345,6 +349,24 @@ int f_sys_open_x(struct event_filler_arguments *args) res = val_to_ring(args, ino, 0, false, 0); CHECK_RES(res); + /* + * fd_flags + */ + if (likely(file)) + { + ol = ppm_get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + } + res = val_to_ring(args, fd_flags, 0, false, 0); + CHECK_RES(res); + return add_sentinel(args); } @@ -845,11 +867,11 @@ static uint32_t ppm_get_tty(void) return tty_nr; } -static bool ppm_is_upper_layer(struct file *file) +static enum ppm_overlay ppm_get_overlay_layer(struct file *file) { // 3.18 is the Kernel version where overlayfs was introduced #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) - return false; + return PPM_NOT_OVERLAY_FS; #else struct dentry * dentry = NULL; struct super_block* sb = NULL; @@ -858,24 +880,24 @@ static bool ppm_is_upper_layer(struct file *file) if(!file) { - return false; + return PPM_NOT_OVERLAY_FS; } dentry = file->f_path.dentry; if(!dentry) { - return false; + return PPM_NOT_OVERLAY_FS; } sb = dentry->d_sb; if(!sb) { - return false; + return PPM_NOT_OVERLAY_FS; } if(sb->s_magic != PPM_OVERLAYFS_SUPER_MAGIC) { - return false; + return PPM_NOT_OVERLAY_FS; } #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) @@ -884,7 +906,7 @@ static bool ppm_is_upper_layer(struct file *file) struct ovl_entry *oe = (struct ovl_entry*)(dentry->d_fsdata); if(!oe) { - return false; + return PPM_OVERLAY_LOWER; } upper_dentry = oe->__upperdentry; } @@ -893,7 +915,7 @@ static bool ppm_is_upper_layer(struct file *file) char *vfs_inode = (char*)dentry->d_inode; if(!vfs_inode) { - return false; + return PPM_OVERLAY_LOWER; } // Pointer arithmetics due to unexported ovl_inode struct @@ -905,15 +927,19 @@ static bool ppm_is_upper_layer(struct file *file) #endif // LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) if(!upper_dentry) { - return false; + return PPM_OVERLAY_LOWER; } upper_ino = upper_dentry->d_inode; if(!upper_ino) { - return false; + return PPM_OVERLAY_LOWER; + } + if(upper_ino->i_ino != 0) + { + return PPM_OVERLAY_UPPER; } - return upper_ino->i_ino != 0; + return PPM_OVERLAY_LOWER; #endif // LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) } @@ -1277,7 +1303,7 @@ int f_proc_startupdate(struct event_filler_arguments *args) long env_len = 0; uint32_t tty_nr = 0; bool exe_writable = false; - bool exe_upper_layer = false; + enum ppm_overlay exe_layer = PPM_NOT_OVERLAY_FS; struct file *exe_file = NULL; uint32_t flags = 0; // execve additional flags unsigned long i_ino = 0; @@ -1374,7 +1400,7 @@ int f_proc_startupdate(struct event_filler_arguments *args) CHECK_RES(res); /* - * exe_writable and exe_upper_layer flags + * exe_writable, exe_upper_layer and exe_lower_layer flags */ exe_file = ppm_get_mm_exe_file(mm); @@ -1403,8 +1429,8 @@ int f_proc_startupdate(struct event_filler_arguments *args) * MAY_OT_BLOCK flag is introduced and avoids the processor to being yield. */ - /* Support exe_upper_layer */ - exe_upper_layer = ppm_is_upper_layer(exe_file); + /* Support exe_upper_layer and exe_lower_layer */ + exe_layer = ppm_get_overlay_layer(exe_file); /* Support exe_from_memfd */ flags |= get_exe_from_memfd(exe_file); @@ -1464,9 +1490,12 @@ int f_proc_startupdate(struct event_filler_arguments *args) flags |= PPM_EXE_WRITABLE; } - if (exe_upper_layer) { + if (exe_layer == PPM_OVERLAY_UPPER) { flags |= PPM_EXE_UPPER_LAYER; } + else if (exe_layer == PPM_OVERLAY_LOWER) { + flags |= PPM_EXE_LOWER_LAYER; + } // write all the additional flags for execve family here... @@ -2961,6 +2990,9 @@ int f_sys_creat_x(struct event_filler_arguments *args) uint64_t ino = 0; int res; int64_t retval; + struct file *file = NULL; + enum ppm_overlay ol; + int32_t fd_flags = 0; /* * fd @@ -2982,7 +3014,7 @@ int f_sys_creat_x(struct event_filler_arguments *args) res = val_to_ring(args, open_modes_to_scap(O_CREAT, modes), 0, false, 0); CHECK_RES(res); - get_fd_dev_ino(retval, &dev, &ino); + get_fd_dev_ino_file(retval, &dev, &ino, &file); /* * dev @@ -2996,6 +3028,24 @@ int f_sys_creat_x(struct event_filler_arguments *args) res = val_to_ring(args, ino, 0, false, 0); CHECK_RES(res); + /* + * fd_flags + */ + if (likely(file)) + { + ol = ppm_get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + } + res = val_to_ring(args, fd_flags, 0, false, 0); + CHECK_RES(res); + return add_sentinel(args); } @@ -3007,6 +3057,7 @@ int f_sys_pipe_x(struct event_filler_arguments *args) int pipefd[2] = {-1, -1}; uint32_t dev = 0; uint64_t ino = 0; + struct file *file = NULL; /* Parameter 1: res (type: PT_ERRNO) */ retval = (int64_t)syscall_get_return_value(current, args->regs); @@ -3045,7 +3096,7 @@ int f_sys_pipe_x(struct event_filler_arguments *args) /* On success, pipe returns `0` */ if(retval == 0) { - get_fd_dev_ino(pipefd[0], &dev, &ino); + get_fd_dev_ino_file(pipefd[0], &dev, &ino, &file); } /* Parameter 4: ino (type: PT_UINT64) */ @@ -3063,6 +3114,7 @@ int f_sys_pipe2_x(struct event_filler_arguments *args) int pipefd[2] = {-1, -1}; uint32_t dev = 0; uint64_t ino = 0; + struct file *file = NULL; /* Parameter 1: res (type: PT_ERRNO) */ retval = (int64_t)syscall_get_return_value(current, args->regs); @@ -3101,7 +3153,7 @@ int f_sys_pipe2_x(struct event_filler_arguments *args) /* On success, pipe returns `0` */ if(retval == 0) { - get_fd_dev_ino(pipefd[0], &dev, &ino); + get_fd_dev_ino_file(pipefd[0], &dev, &ino, &file); } /* Parameter 4: ino (type: PT_UINT64) */ @@ -3530,6 +3582,9 @@ int f_sys_openat_x(struct event_filler_arguments *args) int res; int32_t fd; int64_t retval; + struct file *file = NULL; + enum ppm_overlay ol; + int32_t fd_flags = 0; retval = (int64_t)syscall_get_return_value(current, args->regs); res = val_to_ring(args, retval, 0, false, 0); @@ -3569,7 +3624,7 @@ int f_sys_openat_x(struct event_filler_arguments *args) syscall_get_arguments_deprecated(args, 3, 1, &modes); res = val_to_ring(args, open_modes_to_scap(flags, modes), 0, false, 0); CHECK_RES(res); - get_fd_dev_ino(retval, &dev, &ino); + get_fd_dev_ino_file(retval, &dev, &ino, &file); /* * dev @@ -3581,6 +3636,25 @@ int f_sys_openat_x(struct event_filler_arguments *args) */ res = val_to_ring(args, ino, 0, false, 0); CHECK_RES(res); + + /* + * fd_flags + */ + if (likely(file)) + { + ol = ppm_get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + } + res = val_to_ring(args, fd_flags, 0, false, 0); + CHECK_RES(res); + return add_sentinel(args); } @@ -4952,6 +5026,9 @@ int f_sys_openat2_x(struct event_filler_arguments *args) int res; int32_t fd; int64_t retval; + struct file *file = NULL; + enum ppm_overlay ol; + int32_t fd_flags = 0; #ifdef __NR_openat2 struct open_how how; #endif @@ -5019,7 +5096,7 @@ int f_sys_openat2_x(struct event_filler_arguments *args) res = val_to_ring(args, resolve, 0, true, 0); CHECK_RES(res); - get_fd_dev_ino(retval, &dev, &ino); + get_fd_dev_ino_file(retval, &dev, &ino, &file); /* * dev @@ -5033,6 +5110,24 @@ int f_sys_openat2_x(struct event_filler_arguments *args) res = val_to_ring(args, ino, 0, false, 0); CHECK_RES(res); + /* + * fd_flags + */ + if (likely(file)) + { + ol = ppm_get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + } + res = val_to_ring(args, fd_flags, 0, false, 0); + CHECK_RES(res); + return add_sentinel(args); } @@ -5104,6 +5199,9 @@ int f_sys_open_by_handle_at_x(struct event_filler_arguments *args) long retval = 0; char *pathname = NULL; int32_t mountfd = 0; + struct file *file = NULL; + enum ppm_overlay ol; + int32_t fd_flags = 0; /* Parameter 1: ret (type: PT_FD) */ retval = syscall_get_return_value(current, args->regs); @@ -5151,7 +5249,7 @@ int f_sys_open_by_handle_at_x(struct event_filler_arguments *args) res = val_to_ring(args, (unsigned long)pathname, 0, false, 0); CHECK_RES(res); - get_fd_dev_ino(retval, &dev, &ino); + get_fd_dev_ino_file(retval, &dev, &ino, &file); /* Parameter 5: dev (type: PT_UINT32) */ res = val_to_ring(args, dev, 0, false, 0); @@ -5161,6 +5259,24 @@ int f_sys_open_by_handle_at_x(struct event_filler_arguments *args) res = val_to_ring(args, ino, 0, false, 0); CHECK_RES(res); + /* + * fd_flags + */ + if (likely(file)) + { + ol = ppm_get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; + } + } + res = val_to_ring(args, fd_flags, 0, false, 0); + CHECK_RES(res); + return add_sentinel(args); } @@ -7249,7 +7365,7 @@ int f_sched_prog_exec(struct event_filler_arguments *args) uint32_t tty_nr = 0; uint32_t flags = 0; bool exe_writable = false; - bool exe_upper_layer = false; + enum ppm_overlay exe_layer = PPM_NOT_OVERLAY_FS; struct file *exe_file = NULL; const struct cred *cred = NULL; unsigned long i_ino = 0; @@ -7433,7 +7549,7 @@ int f_sched_prog_exec(struct event_filler_arguments *args) res = val_to_ring(args, loginuid, 0, false, 0); CHECK_RES(res); - /* `exe_writable` and `exe_upper_layer` flag logic */ + /* `exe_writable`, `exe_upper_layer` and `exe_lower_layer` flag logic */ exe_file = ppm_get_mm_exe_file(mm); if(exe_file != NULL) { @@ -7459,8 +7575,8 @@ int f_sched_prog_exec(struct event_filler_arguments *args) * MAY_OT_BLOCK flag is introduced and avoids the processor to being yield. */ - /* Support exe_upper_layer */ - exe_upper_layer = ppm_is_upper_layer(exe_file); + /* Support exe_upper_layer and exe_lower_layer */ + exe_layer = ppm_get_overlay_layer(exe_file); /* Support exe_from_memfd */ flags |= get_exe_from_memfd(exe_file); @@ -7521,10 +7637,14 @@ int f_sched_prog_exec(struct event_filler_arguments *args) flags |= PPM_EXE_WRITABLE; } - if(exe_upper_layer) + if(exe_layer == PPM_OVERLAY_UPPER) { flags |= PPM_EXE_UPPER_LAYER; } + else if(exe_layer == PPM_OVERLAY_LOWER) + { + flags |= PPM_EXE_LOWER_LAYER; + } // write all the additional flags for execve family here... diff --git a/userspace/libscap/scap.h b/userspace/libscap/scap.h index 56be5c1d70..70b8876ff5 100644 --- a/userspace/libscap/scap.h +++ b/userspace/libscap/scap.h @@ -265,6 +265,7 @@ typedef struct scap_threadinfo char exepath[SCAP_MAX_PATH_SIZE+1]; ///< full executable path bool exe_writable; ///< true if the original executable is writable by the same user that spawned it. bool exe_upper_layer; //< True if the original executable belongs to upper layer in overlayfs + bool exe_lower_layer; //< True if the original executable belongs to lower layer in overlayfs bool exe_from_memfd; //< True if the original executable is stored in pathless memory referenced by a memfd char args[SCAP_MAX_ARGS_SIZE+1]; ///< Command line arguments (e.g. "-d1") uint16_t args_len; ///< Command line arguments length diff --git a/userspace/libsinsp/fdinfo.h b/userspace/libsinsp/fdinfo.h index 809942df11..9549fc6851 100644 --- a/userspace/libsinsp/fdinfo.h +++ b/userspace/libsinsp/fdinfo.h @@ -109,6 +109,8 @@ class SINSP_PUBLIC sinsp_fdinfo : public libsinsp::state::table_entry FLAGS_IS_CLONED = (1 << 14), FLAGS_CONNECTION_PENDING = (1 << 15), FLAGS_CONNECTION_FAILED = (1 << 16), + FLAGS_OVERLAY_UPPER = (1 << 17), + FLAGS_OVERLAY_LOWER = (1 << 18), }; sinsp_fdinfo(const std::shared_ptr& dyn_fields = nullptr); @@ -323,6 +325,16 @@ class SINSP_PUBLIC sinsp_fdinfo : public libsinsp::state::table_entry return (m_flags & FLAGS_IS_CLONED) == FLAGS_IS_CLONED; } + inline bool is_overlay_upper() const + { + return (m_flags & FLAGS_OVERLAY_UPPER) == FLAGS_OVERLAY_UPPER; + } + + inline bool is_overlay_lower() const + { + return (m_flags & FLAGS_OVERLAY_LOWER) == FLAGS_OVERLAY_LOWER; + } + void add_filename_raw(std::string_view rawpath); void add_filename(std::string_view fullpath); @@ -422,6 +434,16 @@ class SINSP_PUBLIC sinsp_fdinfo : public libsinsp::state::table_entry m_flags |= FLAGS_IS_CLONED; } + inline void set_overlay_upper() + { + m_flags |= FLAGS_OVERLAY_UPPER; + } + + inline void set_overlay_lower() + { + m_flags |= FLAGS_OVERLAY_LOWER; + } + scap_fd_type m_type = SCAP_FD_UNINITIALIZED; ///< The fd type, e.g. file, directory, IPv4 socket... uint32_t m_openflags = 0; ///< If this FD is a file, the flags that were used when opening it. See the PPM_O_* definitions in driver/ppm_events_public.h. sinsp_sockinfo m_sockinfo = {}; ///< Socket-specific state. This is uninitialized (zero) for non-socket FDs. diff --git a/userspace/libsinsp/parsers.cpp b/userspace/libsinsp/parsers.cpp index 514956cb8c..6b9d509c4f 100644 --- a/userspace/libsinsp/parsers.cpp +++ b/userspace/libsinsp/parsers.cpp @@ -1388,6 +1388,8 @@ void sinsp_parser::parse_clone_exit_caller(sinsp_evt *evt, int64_t child_tid) child_tinfo->m_exe_upper_layer = caller_tinfo->m_exe_upper_layer; + child_tinfo->m_exe_lower_layer = caller_tinfo->m_exe_lower_layer; + child_tinfo->m_exe_from_memfd = caller_tinfo->m_exe_from_memfd; child_tinfo->m_root = caller_tinfo->m_root; @@ -1715,6 +1717,8 @@ void sinsp_parser::parse_clone_exit_child(sinsp_evt *evt) child_tinfo->m_exe_upper_layer = lookup_tinfo->m_exe_upper_layer; + child_tinfo->m_exe_lower_layer = lookup_tinfo->m_exe_lower_layer; + child_tinfo->m_exe_from_memfd = lookup_tinfo->m_exe_from_memfd; child_tinfo->m_root = lookup_tinfo->m_root; @@ -2378,6 +2382,7 @@ void sinsp_parser::parse_execve_exit(sinsp_evt *evt) evt->get_tinfo()->m_exe_writable = ((flags & PPM_EXE_WRITABLE) != 0); evt->get_tinfo()->m_exe_upper_layer = ((flags & PPM_EXE_UPPER_LAYER) != 0); evt->get_tinfo()->m_exe_from_memfd = ((flags & PPM_EXE_FROM_MEMFD) != 0); + evt->get_tinfo()->m_exe_lower_layer = ((flags & PPM_EXE_LOWER_LAYER) != 0); } // Get capabilities @@ -2564,6 +2569,7 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) uint16_t etype = evt->get_type(); uint32_t dev = 0; uint64_t ino = 0; + uint32_t fd_flags = 0; bool lastevent_retrieved = false; if(evt->get_tinfo() == nullptr) @@ -2598,6 +2604,10 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) if (evt->get_num_params() > 5) { ino = evt->get_param(5)->as(); + if (evt->get_num_params() > 6) + { + fd_flags = evt->get_param(6)->as(); + } } } @@ -2635,6 +2645,10 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) if (evt->get_num_params() > 4) { ino = evt->get_param(4)->as(); + if (evt->get_num_params() > 5) + { + fd_flags = evt->get_param(5)->as(); + } } } @@ -2681,6 +2695,10 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) if (evt->get_num_params() > 6) { ino = evt->get_param(6)->as(); + if (evt->get_num_params() > 7) + { + fd_flags = evt->get_param(7)->as(); + } } } else if(etype == PPME_SYSCALL_OPENAT2_X && evt->get_num_params() > 6) @@ -2689,6 +2707,10 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) if (evt->get_num_params() > 7) { ino = evt->get_param(7)->as(); + if (evt->get_num_params() > 8) + { + fd_flags = evt->get_param(8)->as(); + } } } @@ -2729,6 +2751,10 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) if (evt->get_num_params() > 5) { ino = evt->get_param(5)->as(); + if (evt->get_num_params() > 6) + { + fd_flags = evt->get_param(6)->as(); + } } } @@ -2769,6 +2795,14 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) fdi->m_ino = ino; fdi->add_filename_raw(name); fdi->add_filename(fullpath); + if(fd_flags & PPM_FD_UPPER_LAYER) + { + fdi->set_overlay_upper(); + } + if(fd_flags & PPM_FD_LOWER_LAYER) + { + fdi->set_overlay_lower(); + } // // Add the fd to the table. diff --git a/userspace/libsinsp/sinsp_filtercheck_fd.cpp b/userspace/libsinsp/sinsp_filtercheck_fd.cpp index ee916b31e6..a6b48242cb 100644 --- a/userspace/libsinsp/sinsp_filtercheck_fd.cpp +++ b/userspace/libsinsp/sinsp_filtercheck_fd.cpp @@ -94,6 +94,8 @@ static const filtercheck_field_info sinsp_filter_check_fd_fields[] = {PT_INT64, EPF_NONE, PF_DEC, "fd.ino", "FD Inode Number", "inode number of the referenced file"}, {PT_CHARBUF, EPF_NONE, PF_NA, "fd.nameraw", "FD Name Raw", "FD full name raw. Just like fd.name, but only used if fd is a file path. File path is kept raw with limited sanitization and without deriving the absolute path."}, {PT_CHARBUF, EPF_IS_LIST | EPF_ARG_ALLOWED | EPF_NO_RHS | EPF_NO_TRANSFORMER, PF_DEC, "fd.types", "FD Type", "List of FD types in used. Can be passed an fd number e.g. fd.types[0] to get the type of stdout as a single item list."}, + {PT_BOOL, EPF_NONE, PF_NA, "fd.is_upper_layer", "FD Upper Layer", "'true' if the fd is of a file in the upper layer of an overlayfs."}, + {PT_BOOL, EPF_NONE, PF_NA, "fd.is_lower_layer", "FD Lower Layer", "'true' if the fd is of a file in the lower layer of an overlayfs."}, }; sinsp_filter_check_fd::sinsp_filter_check_fd() @@ -1388,6 +1390,28 @@ uint8_t* sinsp_filter_check_fd::extract_single(sinsp_evt *evt, uint32_t* len, bo RETURN_EXTRACT_STRING(m_tstr); } break; + case TYPE_FDUPPER: + { + if(m_fdinfo == NULL) + { + return NULL; + } + + m_val.u32 = m_fdinfo->is_overlay_upper(); + RETURN_EXTRACT_VAR(m_val.u32); + } + break; + case TYPE_FDLOWER: + { + if(m_fdinfo == NULL) + { + return NULL; + } + + m_val.u32 = m_fdinfo->is_overlay_lower(); + RETURN_EXTRACT_VAR(m_val.u32); + } + break; default: ASSERT(false); } diff --git a/userspace/libsinsp/sinsp_filtercheck_fd.h b/userspace/libsinsp/sinsp_filtercheck_fd.h index 0f94bbeeb8..1cc6ee22da 100644 --- a/userspace/libsinsp/sinsp_filtercheck_fd.h +++ b/userspace/libsinsp/sinsp_filtercheck_fd.h @@ -69,6 +69,8 @@ class sinsp_filter_check_fd : public sinsp_filter_check TYPE_INO = 41, TYPE_FDNAMERAW = 42, TYPE_FDTYPES = 43, + TYPE_FDUPPER = 44, + TYPE_FDLOWER = 45, }; sinsp_filter_check_fd(); diff --git a/userspace/libsinsp/sinsp_filtercheck_thread.cpp b/userspace/libsinsp/sinsp_filtercheck_thread.cpp index 2d59cfbd50..d137396ea2 100644 --- a/userspace/libsinsp/sinsp_filtercheck_thread.cpp +++ b/userspace/libsinsp/sinsp_filtercheck_thread.cpp @@ -86,6 +86,7 @@ static const filtercheck_field_info sinsp_filter_check_thread_fields[] = {PT_RELTIME, EPF_NONE, PF_DEC, "proc.ppid.ts", "Parent Process start ts", "Start of parent process as epoch timestamp in nanoseconds."}, {PT_BOOL, EPF_NONE, PF_NA, "proc.is_exe_writable", "Process Executable Is Writable", "'true' if this process' executable file is writable by the same user that spawned the process."}, {PT_BOOL, EPF_NONE, PF_NA, "proc.is_exe_upper_layer", "Process Executable Is In Upper Layer", "'true' if this process' executable file is in upper layer in overlayfs. This field value can only be trusted if the underlying kernel version is greater or equal than 3.18.0, since overlayfs was introduced at that time."}, + {PT_BOOL, EPF_NONE, PF_NA, "proc.is_exe_lower_layer", "Process Executable Is In Lower Layer", "'true' if this process' executable file is in lower layer in overlayfs. This field value can only be trusted if the underlying kernel version is greater or equal than 3.18.0, since overlayfs was introduced at that time."}, {PT_BOOL, EPF_NONE, PF_NA, "proc.is_exe_from_memfd", "Process Executable Is Stored In Memfd", "'true' if the executable file of the current process is an anonymous file created using memfd_create() and is being executed by referencing its file descriptor (fd). This type of file exists only in memory and not on disk. Relevant to detect malicious in-memory code injection. Requires kernel version greater or equal to 3.17.0."}, {PT_BOOL, EPF_NONE, PF_NA, "proc.is_sid_leader", "Process Is Process Session Leader", "'true' if this process is the leader of the process session, proc.sid == proc.vpid. For host processes vpid reflects pid."}, {PT_BOOL, EPF_NONE, PF_NA, "proc.is_vpgid_leader", "Process Is Virtual Process Group Leader", "'true' if this process is the leader of the virtual process group, proc.vpgid == proc.vpid. For host processes vpgid and vpid reflect pgid and pid. Can help to distinguish if the process was 'directly' executed for instance in a tty (similar to bash history logging, `is_vpgid_leader` would be 'true') or executed as descendent process in the same process group which for example is the case when subprocesses are spawned from a script (`is_vpgid_leader` would be 'false')."}, @@ -1511,6 +1512,9 @@ uint8_t* sinsp_filter_check_thread::extract_single(sinsp_evt *evt, uint32_t* len case TYPE_IS_EXE_UPPER_LAYER: m_val.u32 = tinfo->m_exe_upper_layer; RETURN_EXTRACT_VAR(m_val.u32); + case TYPE_IS_EXE_LOWER_LAYER: + m_val.u32 = tinfo->m_exe_lower_layer; + RETURN_EXTRACT_VAR(m_val.u32); case TYPE_IS_EXE_FROM_MEMFD: m_val.u32 = tinfo->m_exe_from_memfd; RETURN_EXTRACT_VAR(m_val.u32); diff --git a/userspace/libsinsp/sinsp_filtercheck_thread.h b/userspace/libsinsp/sinsp_filtercheck_thread.h index e3af894b97..5822bd2c41 100644 --- a/userspace/libsinsp/sinsp_filtercheck_thread.h +++ b/userspace/libsinsp/sinsp_filtercheck_thread.h @@ -66,6 +66,7 @@ class sinsp_filter_check_thread : public sinsp_filter_check TYPE_PPID_CLONE_TS, TYPE_IS_EXE_WRITABLE, TYPE_IS_EXE_UPPER_LAYER, + TYPE_IS_EXE_LOWER_LAYER, TYPE_IS_EXE_FROM_MEMFD, TYPE_IS_SID_LEADER, TYPE_IS_VPGID_LEADER, diff --git a/userspace/libsinsp/test/state.ut.cpp b/userspace/libsinsp/test/state.ut.cpp index ac5350b245..f281c34e5d 100644 --- a/userspace/libsinsp/test/state.ut.cpp +++ b/userspace/libsinsp/test/state.ut.cpp @@ -308,7 +308,7 @@ TEST(thread_manager, table_access) { // note: used for regression checks, keep this updated as we make // new fields available - static const int s_threadinfo_static_fields_count = 27; + static const int s_threadinfo_static_fields_count = 28; sinsp inspector; auto table = static_cast*>(inspector.m_thread_manager.get()); diff --git a/userspace/libsinsp/threadinfo.cpp b/userspace/libsinsp/threadinfo.cpp index 1aea381845..7b08523dd9 100644 --- a/userspace/libsinsp/threadinfo.cpp +++ b/userspace/libsinsp/threadinfo.cpp @@ -69,6 +69,7 @@ libsinsp::state::static_struct::field_infos sinsp_threadinfo::static_fields() co define_static_field(ret, this, m_exepath, "exe_path"); define_static_field(ret, this, m_exe_writable, "exe_writable"); define_static_field(ret, this, m_exe_upper_layer, "exe_upper_layer"); + define_static_field(ret, this, m_exe_lower_layer, "exe_lower_layer"); define_static_field(ret, this, m_exe_from_memfd, "exe_from_memfd"); define_static_field(ret, this, m_args_table_adapter.table_ptr(), "args", true); define_static_field(ret, this, m_env_table_adapter.table_ptr(), "env", true); @@ -156,6 +157,7 @@ void sinsp_threadinfo::init() m_filtered_out = false; m_exe_writable = false; m_exe_upper_layer = false; + m_exe_lower_layer = false; m_exe_from_memfd = false; } @@ -465,6 +467,7 @@ void sinsp_threadinfo::init(scap_threadinfo* pi) m_exepath = pi->exepath; m_exe_writable = pi->exe_writable; m_exe_upper_layer = pi->exe_upper_layer; + m_exe_lower_layer = pi->exe_lower_layer; m_exe_from_memfd = pi->exe_from_memfd; /* We cannot obtain the reaper_tid from a /proc scan */ diff --git a/userspace/libsinsp/threadinfo.h b/userspace/libsinsp/threadinfo.h index 82fa9c3728..b9fc2e30ee 100644 --- a/userspace/libsinsp/threadinfo.h +++ b/userspace/libsinsp/threadinfo.h @@ -498,6 +498,7 @@ class SINSP_PUBLIC sinsp_threadinfo : public libsinsp::state::table_entry std::string m_exepath; ///< full executable path bool m_exe_writable; bool m_exe_upper_layer; ///< True if the executable file belongs to upper layer in overlayfs + bool m_exe_lower_layer; ///< True if the executable file belongs to lower layer in overlayfs bool m_exe_from_memfd; ///< True if the executable is stored in fileless memory referenced by memfd std::vector m_args; ///< Command line arguments (e.g. "-d1") std::vector m_env; ///< Environment variables From b3bebd593ce9c52f2829f3b3db792723174e87ce Mon Sep 17 00:00:00 2001 From: Eddy Duer Date: Thu, 8 Aug 2024 12:25:59 +0300 Subject: [PATCH 2/7] Changes after code review Signed-off-by: Eddy Duer --- driver/bpf/filler_helpers.h | 23 ++++++++- driver/bpf/fillers.h | 48 ++++++++----------- driver/event_table.c | 12 +++-- .../helpers/extract/extract_from_kernel.h | 3 +- .../attached/events/sched_process_exec.bpf.c | 3 +- .../syscall_dispatched_events/creat.bpf.c | 8 ++-- .../syscall_dispatched_events/execve.bpf.c | 4 +- .../syscall_dispatched_events/execveat.bpf.c | 4 +- .../syscall_dispatched_events/open.bpf.c | 8 ++-- .../open_by_handle_at.bpf.c | 8 ++-- .../syscall_dispatched_events/openat.bpf.c | 8 ++-- .../syscall_dispatched_events/openat2.bpf.c | 8 ++-- driver/ppm_fillers.c | 10 ++-- userspace/libsinsp/parsers.cpp | 12 ++--- 14 files changed, 86 insertions(+), 73 deletions(-) diff --git a/driver/bpf/filler_helpers.h b/driver/bpf/filler_helpers.h index 01c3cd8ce7..6e217d5e9a 100644 --- a/driver/bpf/filler_helpers.h +++ b/driver/bpf/filler_helpers.h @@ -280,7 +280,28 @@ static __always_inline unsigned long bpf_encode_dev(dev_t dev) return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12); } -static __always_inline void bpf_get_fd_dev_ino_file(int fd, unsigned long *dev, unsigned long *ino, struct file **file) +static __always_inline void bpf_get_ino_from_fd(int fd, unsigned long *ino) +{ + struct super_block *sb; + struct inode *inode; + struct file *file; + dev_t kdev; + + if (fd < 0) + return; + + file = bpf_fget(fd); + if (!file) + return; + + inode = _READ(file->f_inode); + if (!inode) + return; + + *ino = _READ(inode->i_ino); +} + +static __always_inline void bpf_get_dev_ino_file_from_fd(int fd, unsigned long *dev, unsigned long *ino, struct file **file) { struct super_block *sb; struct inode *inode; diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index 73e895138f..2486ecb45f 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -404,7 +404,7 @@ FILLER(sys_open_x, true) long retval; int res; struct file *file = NULL; - unsigned int fd_flags = 0; + unsigned short fd_flags = 0; /* Parameter 1: ret (type: PT_FD) */ retval = bpf_syscall_get_retval(data->ctx); @@ -430,7 +430,7 @@ FILLER(sys_open_x, true) res = bpf_push_u32_to_ring(data, mode); CHECK_RES(res); - bpf_get_fd_dev_ino_file(retval, &dev, &ino, &file); + bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); /* Parameter 5: dev (type: PT_UINT32) */ res = bpf_push_u32_to_ring(data, (uint32_t)dev); @@ -440,7 +440,7 @@ FILLER(sys_open_x, true) res = bpf_push_u64_to_ring(data, (uint64_t)ino); CHECK_RES(res); - /* Parameter 7: fd_flags (type: PT_UINT32) */ + /* Parameter 7: fd_flags (type: PT_FLAGS16) */ if (likely(file)) { enum ppm_overlay ol = get_overlay_layer(file); @@ -453,7 +453,7 @@ FILLER(sys_open_x, true) fd_flags |= PPM_FD_LOWER_LAYER; } } - return bpf_push_u32_to_ring(data, (uint32_t)fd_flags); + return bpf_push_u16_to_ring(data, (uint16_t)fd_flags); } FILLER(sys_read_e, true) @@ -3215,7 +3215,7 @@ FILLER(sys_openat_x, true) int32_t fd; int res; struct file *file = NULL; - unsigned int fd_flags = 0; + unsigned short fd_flags = 0; retval = bpf_syscall_get_retval(data->ctx); res = bpf_push_s64_to_ring(data, retval); @@ -3257,7 +3257,7 @@ FILLER(sys_openat_x, true) res = bpf_push_u32_to_ring(data, mode); CHECK_RES(res); - bpf_get_fd_dev_ino_file(retval, &dev, &ino, &file); + bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); /* * Device @@ -3286,7 +3286,7 @@ FILLER(sys_openat_x, true) fd_flags |= PPM_FD_LOWER_LAYER; } } - return bpf_push_u32_to_ring(data, (uint32_t)fd_flags); + return bpf_push_u16_to_ring(data, (uint16_t)fd_flags); } FILLER(sys_openat2_e, true) @@ -3368,7 +3368,7 @@ FILLER(sys_openat2_x, true) int32_t fd; int res; struct file *file = NULL; - unsigned int fd_flags = 0; + unsigned short fd_flags = 0; #ifdef __NR_openat2 struct open_how how; #endif @@ -3434,7 +3434,7 @@ FILLER(sys_openat2_x, true) res = bpf_push_u32_to_ring(data, resolve); CHECK_RES(res); - bpf_get_fd_dev_ino_file(retval, &dev, &ino, &file); + bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); /* * dev @@ -3463,7 +3463,7 @@ FILLER(sys_openat2_x, true) fd_flags |= PPM_FD_LOWER_LAYER; } } - return bpf_push_u32_to_ring(data, (uint32_t)fd_flags); + return bpf_push_u16_to_ring(data, (uint16_t)fd_flags); } FILLER(sys_open_by_handle_at_x, true) @@ -3512,8 +3512,8 @@ FILLER(sys_open_by_handle_at_x, true) res = bpf_push_u64_to_ring(data, 0); CHECK_RES(res); - /* Parameter 7: fd_flags (type: PT_UINT32) */ - return bpf_push_u32_to_ring(data, 0); + /* Parameter 7: fd_flags (type: PT_FLAGS16) */ + return bpf_push_u16_to_ring(data, 0); } @@ -3523,9 +3523,9 @@ FILLER(open_by_handle_at_x_extra_tail_1, true) struct file *f = NULL; unsigned long dev = 0; unsigned long ino = 0; - unsigned int fd_flags = 0; + unsigned short fd_flags = 0; - bpf_get_fd_dev_ino_file(retval, &dev, &ino, &f); + bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &f); if(f == NULL) { @@ -3551,7 +3551,7 @@ FILLER(open_by_handle_at_x_extra_tail_1, true) res = bpf_push_u64_to_ring(data, ino); CHECK_RES(res); - /* Parameter 7: fd_flags (type: PT_UINT32) */ + /* Parameter 7: fd_flags (type: PT_FLAGS16) */ if (likely(f)) { enum ppm_overlay ol = get_overlay_layer(f); @@ -3564,7 +3564,7 @@ FILLER(open_by_handle_at_x_extra_tail_1, true) fd_flags |= PPM_FD_LOWER_LAYER; } } - return bpf_push_u32_to_ring(data, (uint32_t)fd_flags); + return bpf_push_u16_to_ring(data, (uint16_t)fd_flags); } FILLER(sys_io_uring_setup_x, true) @@ -4646,7 +4646,7 @@ FILLER(sys_creat_x, true) long retval; int res; struct file *file = NULL; - unsigned int fd_flags = 0; + unsigned short fd_flags = 0; retval = bpf_syscall_get_retval(data->ctx); res = bpf_push_s64_to_ring(data, retval); @@ -4667,7 +4667,7 @@ FILLER(sys_creat_x, true) res = bpf_push_u32_to_ring(data, mode); CHECK_RES(res); - bpf_get_fd_dev_ino_file(retval, &dev, &ino, &file); + bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); /* * Device @@ -4696,7 +4696,7 @@ FILLER(sys_creat_x, true) fd_flags |= PPM_FD_LOWER_LAYER; } } - return bpf_push_u32_to_ring(data, (uint32_t)fd_flags); + return bpf_push_u16_to_ring(data, (uint16_t)fd_flags); } FILLER(sys_pipe_x, true) @@ -4724,13 +4724,10 @@ FILLER(sys_pipe_x, true) CHECK_RES(res); unsigned long ino = 0; - /* Not used, we use it just to call `bpf_get_fd_dev_ino_file` */ - unsigned long dev = 0; - struct file *file = NULL; /* On success, pipe returns `0` */ if(retval == 0) { - bpf_get_fd_dev_ino_file(pipefd[0], &dev, &ino, &file); + bpf_get_ino_from_fd(pipefd[0], &ino); } /* Parameter 4: ino (type: PT_UINT64) */ @@ -4762,13 +4759,10 @@ FILLER(sys_pipe2_x, true) CHECK_RES(res); unsigned long ino = 0; - /* Not used, we use it just to call `bpf_get_fd_dev_ino_file` */ - unsigned long dev = 0; - struct file *file = NULL; /* On success, pipe returns `0` */ if(retval == 0) { - bpf_get_fd_dev_ino_file(pipefd[0], &dev, &ino, &file); + bpf_get_ino_from_fd(pipefd[0], &ino); } /* Parameter 4: ino (type: PT_UINT64) */ diff --git a/driver/event_table.c b/driver/event_table.c index 272bfc8123..aa661e64a2 100644 --- a/driver/event_table.c +++ b/driver/event_table.c @@ -53,7 +53,8 @@ const struct ppm_event_info g_event_info[] = { [PPME_GENERIC_E] = {"syscall", EC_OTHER | EC_SYSCALL, EF_NONE, 2, {{"ID", PT_SYSCALLID, PF_DEC}, {"nativeID", PT_UINT16, PF_DEC} } }, [PPME_GENERIC_X] = {"syscall", EC_OTHER | EC_SYSCALL, EF_NONE, 1, {{"ID", PT_SYSCALLID, PF_DEC} } }, [PPME_SYSCALL_OPEN_E] = {"open", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 3, {{"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT} } }, - [PPME_SYSCALL_OPEN_X] = {"open", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 7, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_CLOSE_E] = {"close", EC_IO_OTHER | EC_SYSCALL, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } }, + [PPME_SYSCALL_OPEN_X] = {"open", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 7, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_FLAGS16, PF_HEX} } }, + [PPME_SYSCALL_CLOSE_E] = {"close", EC_IO_OTHER | EC_SYSCALL, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } }, [PPME_SYSCALL_CLOSE_X] = {"close", EC_IO_OTHER | EC_SYSCALL, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_ERRNO, PF_DEC} } }, [PPME_SYSCALL_READ_E] = {"read", EC_IO_READ | EC_SYSCALL, EF_USES_FD | EF_READS_FROM_FD, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_READ_X] = {"read", EC_IO_READ | EC_SYSCALL, EF_USES_FD | EF_READS_FROM_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, @@ -108,7 +109,8 @@ const struct ppm_event_info g_event_info[] = { [PPME_SOCKET_ACCEPT4_E] = {"accept", EC_NET | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 1, {{"flags", PT_INT32, PF_HEX} } }, [PPME_SOCKET_ACCEPT4_X] = {"accept", EC_NET | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 3, {{"fd", PT_FD, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA}, {"queuepct", PT_UINT8, PF_DEC} } }, [PPME_SYSCALL_CREAT_E] = {"creat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 2, {{"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT} } }, - [PPME_SYSCALL_CREAT_X] = {"creat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_PIPE_E] = {"pipe", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, + [PPME_SYSCALL_CREAT_X] = {"creat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_FLAGS16, PF_HEX} } }, + [PPME_SYSCALL_PIPE_E] = {"pipe", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, [PPME_SYSCALL_PIPE_X] = {"pipe", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"fd1", PT_FD, PF_DEC}, {"fd2", PT_FD, PF_DEC}, {"ino", PT_UINT64, PF_DEC} } }, [PPME_SYSCALL_EVENTFD_E] = {"eventfd", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 2, {{"initval", PT_UINT64, PF_DEC}, {"flags", PT_UINT32, PF_HEX} } }, [PPME_SYSCALL_EVENTFD_X] = {"eventfd", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_FD, PF_DEC} } }, @@ -357,7 +359,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_SYSCALL_MKDIRAT_E] = {"mkdirat", EC_FILE | EC_SYSCALL, EF_NONE, 0}, [PPME_SYSCALL_MKDIRAT_X] = {"mkdirat", EC_FILE | EC_SYSCALL, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"path", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"mode", PT_UINT32, PF_HEX} } }, [PPME_SYSCALL_OPENAT_2_E] = {"openat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(0)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT} } }, - [PPME_SYSCALL_OPENAT_2_X] = {"openat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 8, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_UINT32, PF_DEC} } }, + [PPME_SYSCALL_OPENAT_2_X] = {"openat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 8, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_FLAGS16, PF_HEX} } }, [PPME_SYSCALL_LINK_2_E] = {"link", EC_FILE | EC_SYSCALL, EF_NONE, 0}, [PPME_SYSCALL_LINK_2_X] = {"link", EC_FILE | EC_SYSCALL, EF_NONE, 3, {{"res", PT_ERRNO, PF_DEC}, {"oldpath", PT_FSPATH, PF_NA}, {"newpath", PT_FSPATH, PF_NA} } }, [PPME_SYSCALL_LINKAT_2_E] = {"linkat", EC_FILE | EC_SYSCALL, EF_NONE, 0}, @@ -377,7 +379,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_CONTAINER_JSON_2_E] = {"container", EC_PROCESS | EC_METAEVENT, EF_MODIFIES_STATE | EF_LARGE_PAYLOAD, 1, {{"json", PT_CHARBUF, PF_NA} } }, /// TODO: do we need SKIPPARSERESET flag? [PPME_CONTAINER_JSON_2_X] = {"NA", EC_UNKNOWN, EF_UNUSED, 0}, [PPME_SYSCALL_OPENAT2_E] = {"openat2", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags} } }, - [PPME_SYSCALL_OPENAT2_X] = {"openat2", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 9, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_UINT32, PF_DEC} } }, + [PPME_SYSCALL_OPENAT2_X] = {"openat2", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 9, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_FLAGS16, PF_HEX} } }, [PPME_SYSCALL_MPROTECT_E] = {"mprotect", EC_MEMORY | EC_SYSCALL, EF_NONE, 3, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags} } }, [PPME_SYSCALL_MPROTECT_X] = {"mprotect", EC_MEMORY | EC_SYSCALL, EF_NONE, 1, {{"res", PT_ERRNO, PF_DEC} } }, [PPME_SYSCALL_EXECVEAT_E] = {"execveat", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE, 3, {{"dirfd", PT_FD, PF_DEC}, {"pathname", PT_FSRELPATH, PF_NA, DIRFD_PARAM(0)}, {"flags", PT_FLAGS32, PF_HEX, execveat_flags} } }, @@ -387,7 +389,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_SYSCALL_CLONE3_E] = {"clone3", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE, 0}, [PPME_SYSCALL_CLONE3_X] = {"clone3", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE, 21, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"vtid", PT_PID, PF_DEC}, {"vpid", PT_PID, PF_DEC}, {"pidns_init_start_ts", PT_UINT64, PF_DEC} } }, [PPME_SYSCALL_OPEN_BY_HANDLE_AT_E] = {"open_by_handle_at", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, - [PPME_SYSCALL_OPEN_BY_HANDLE_AT_X] = {"open_by_handle_at", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 7, {{"fd", PT_FD, PF_DEC}, {"mountfd", PT_FD, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"path", PT_FSPATH, PF_NA}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_UINT32, PF_DEC} } }, + [PPME_SYSCALL_OPEN_BY_HANDLE_AT_X] = {"open_by_handle_at", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 7, {{"fd", PT_FD, PF_DEC}, {"mountfd", PT_FD, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"path", PT_FSPATH, PF_NA}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_FLAGS16, PF_HEX} } }, [PPME_SYSCALL_IO_URING_SETUP_E] = {"io_uring_setup", EC_IO_OTHER | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, [PPME_SYSCALL_IO_URING_SETUP_X] = {"io_uring_setup", EC_IO_OTHER | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 8, {{"res", PT_ERRNO, PF_DEC}, {"entries", PT_UINT32, PF_DEC}, {"sq_entries", PT_UINT32, PF_DEC},{"cq_entries", PT_UINT32, PF_DEC},{"flags", PT_FLAGS32, PF_HEX, io_uring_setup_flags},{"sq_thread_cpu", PT_UINT32, PF_DEC}, {"sq_thread_idle", PT_UINT32, PF_DEC},{"features", PT_FLAGS32, PF_HEX, io_uring_setup_feats}}}, [PPME_SYSCALL_IO_URING_ENTER_E] = {"io_uring_enter", EC_IO_OTHER | EC_SYSCALL, EF_NONE, 0}, diff --git a/driver/modern_bpf/helpers/extract/extract_from_kernel.h b/driver/modern_bpf/helpers/extract/extract_from_kernel.h index 88815abed5..4c58865977 100644 --- a/driver/modern_bpf/helpers/extract/extract_from_kernel.h +++ b/driver/modern_bpf/helpers/extract/extract_from_kernel.h @@ -903,8 +903,9 @@ static __always_inline bool extract__exe_from_memfd(struct file *file) * @param fd generic file descriptor. * @param dev pointer to the device number we have to fill. * @param ino pointer to the inode number we have to fill. + * @param ol pointer to the overlay layer we have to fill. */ -static __always_inline void extract__dev_ino_and_file_from_fd(int32_t fd, dev_t *dev, uint64_t *ino, enum ppm_overlay *ol) +static __always_inline void extract__dev_ino_overlay_from_fd(int32_t fd, dev_t *dev, uint64_t *ino, enum ppm_overlay *ol) { struct file *f = extract__file_struct_from_fd(fd); if(!f) diff --git a/driver/modern_bpf/programs/attached/events/sched_process_exec.bpf.c b/driver/modern_bpf/programs/attached/events/sched_process_exec.bpf.c index 512cc26342..aa4745f880 100644 --- a/driver/modern_bpf/programs/attached/events/sched_process_exec.bpf.c +++ b/driver/modern_bpf/programs/attached/events/sched_process_exec.bpf.c @@ -166,12 +166,11 @@ int BPF_PROG(t1_sched_p_exec, struct inode *exe_inode = extract__exe_inode_from_task(task); struct file *exe_file = extract__exe_file_from_task(task); - enum ppm_overlay overlay; if(extract__exe_writable(task, exe_inode)) { flags |= PPM_EXE_WRITABLE; } - overlay = extract__overlay_layer(exe_file); + enum ppm_overlay overlay = extract__overlay_layer(exe_file); if(overlay == PPM_OVERLAY_UPPER) { flags |= PPM_EXE_UPPER_LAYER; diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c index 102e09baeb..72748bef88 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c @@ -75,11 +75,11 @@ int BPF_PROG(creat_x, dev_t dev = 0; uint64_t ino = 0; enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; - uint32_t fd_flags = 0; + uint16_t fd_flags = 0; if(ret > 0) { - extract__dev_ino_and_file_from_fd(ret, &dev, &ino, &ol); + extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); } /* Parameter 4: dev (type: PT_UINT32) */ @@ -88,7 +88,7 @@ int BPF_PROG(creat_x, /* Parameter 5: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); - /* Parameter 6: fd_flags (type: PT_UINT32) */ + /* Parameter 6: fd_flags (type: PT_FLAGS16) */ if(ol == PPM_OVERLAY_UPPER) { fd_flags |= PPM_FD_UPPER_LAYER; @@ -97,7 +97,7 @@ int BPF_PROG(creat_x, { fd_flags |= PPM_FD_LOWER_LAYER; } - auxmap__store_u32_param(auxmap, fd_flags); + auxmap__store_u16_param(auxmap, fd_flags); /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execve.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execve.bpf.c index b09e983189..5997df139c 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execve.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execve.bpf.c @@ -226,13 +226,11 @@ int BPF_PROG(t1_execve_x, struct inode *exe_inode = extract__exe_inode_from_task(task); struct file *exe_file = extract__exe_file_from_task(task); - enum ppm_overlay overlay; - if(extract__exe_writable(task, exe_inode)) { flags |= PPM_EXE_WRITABLE; } - overlay = extract__overlay_layer(exe_file); + enum ppm_overlay overlay = extract__overlay_layer(exe_file); if(overlay == PPM_OVERLAY_UPPER) { flags |= PPM_EXE_UPPER_LAYER; diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execveat.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execveat.bpf.c index 388661dfd2..7bfa1215f8 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execveat.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/execveat.bpf.c @@ -240,13 +240,11 @@ int BPF_PROG(t1_execveat_x, struct inode *exe_inode = extract__exe_inode_from_task(task); struct file *exe_file = extract__exe_file_from_task(task); - enum ppm_overlay overlay; - if(extract__exe_writable(task, exe_inode)) { flags |= PPM_EXE_WRITABLE; } - overlay = extract__overlay_layer(exe_file); + enum ppm_overlay overlay = extract__overlay_layer(exe_file); if(overlay == PPM_OVERLAY_UPPER) { flags |= PPM_EXE_UPPER_LAYER; diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c index 07cc3517be..aaac0cd03d 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c @@ -86,11 +86,11 @@ int BPF_PROG(open_x, dev_t dev = 0; uint64_t ino = 0; enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; - uint32_t fd_flags = 0; + uint16_t fd_flags = 0; if(ret > 0) { - extract__dev_ino_and_file_from_fd(ret, &dev, &ino, &ol); + extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); } /* Parameter 5: dev (type: PT_UINT32) */ @@ -99,7 +99,7 @@ int BPF_PROG(open_x, /* Parameter 6: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); - /* Parameter 7: fd_flags (type: PT_UINT32) */ + /* Parameter 7: fd_flags (type: PT_FLAGS16) */ if(ol == PPM_OVERLAY_UPPER) { fd_flags |= PPM_FD_UPPER_LAYER; @@ -108,7 +108,7 @@ int BPF_PROG(open_x, { fd_flags |= PPM_FD_LOWER_LAYER; } - auxmap__store_u32_param(auxmap, fd_flags); + auxmap__store_u16_param(auxmap, fd_flags); /*=============================== COLLECT PARAMETERS ===========================*/ diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c index f3945a7e5c..568a2a2b8a 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c @@ -85,7 +85,7 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) dev_t dev = 0; uint64_t ino = 0; enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; - uint32_t fd_flags = 0; + uint16_t fd_flags = 0; struct auxiliary_map *auxmap = auxmap__get(); if(!auxmap) @@ -109,7 +109,7 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) auxmap__store_empty_param(auxmap); } - extract__dev_ino_and_file_from_fd(ret, &dev, &ino, &ol); + extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); } else { @@ -122,7 +122,7 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) /* Parameter 6: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); - /* Parameter 7: fd_flags (type: PT_UINT32) */ + /* Parameter 7: fd_flags (type: PT_FLAGS16) */ if(ol == PPM_OVERLAY_UPPER) { fd_flags |= PPM_FD_UPPER_LAYER; @@ -131,7 +131,7 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) { fd_flags |= PPM_FD_LOWER_LAYER; } - auxmap__store_u32_param(auxmap, fd_flags); + auxmap__store_u16_param(auxmap, fd_flags); /*=============================== COLLECT PARAMETERS ===========================*/ diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c index 83bb93fc83..87e5270f0f 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c @@ -103,11 +103,11 @@ int BPF_PROG(openat_x, dev_t dev = 0; uint64_t ino = 0; enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; - uint32_t fd_flags = 0; + uint16_t fd_flags = 0; if(ret > 0) { - extract__dev_ino_and_file_from_fd(ret, &dev, &ino, &ol); + extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); } /* Parameter 6: dev (type: PT_UINT32) */ @@ -116,7 +116,7 @@ int BPF_PROG(openat_x, /* Parameter 7: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); - /* Parameter 8: fd_flags (type: PT_UINT32) */ + /* Parameter 8: fd_flags (type: PT_FLAGS16) */ if(ol == PPM_OVERLAY_UPPER) { fd_flags |= PPM_FD_UPPER_LAYER; @@ -125,7 +125,7 @@ int BPF_PROG(openat_x, { fd_flags |= PPM_FD_LOWER_LAYER; } - auxmap__store_u32_param(auxmap, fd_flags); + auxmap__store_u16_param(auxmap, fd_flags); /*=============================== COLLECT PARAMETERS ===========================*/ diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c index 6de8c514d6..e8928d6818 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c @@ -115,11 +115,11 @@ int BPF_PROG(openat2_x, dev_t dev = 0; uint64_t ino = 0; enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; - uint32_t fd_flags = 0; + uint16_t fd_flags = 0; if(ret > 0) { - extract__dev_ino_and_file_from_fd(ret, &dev, &ino, &ol); + extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); } /* Parameter 7: dev (type: PT_UINT32) */ @@ -128,7 +128,7 @@ int BPF_PROG(openat2_x, /* Parameter 8: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); - /* Parameter 9: fd_flags (type: PT_UINT32) */ + /* Parameter 9: fd_flags (type: PT_FLAGS16) */ if(ol == PPM_OVERLAY_UPPER) { fd_flags |= PPM_FD_UPPER_LAYER; @@ -137,7 +137,7 @@ int BPF_PROG(openat2_x, { fd_flags |= PPM_FD_LOWER_LAYER; } - auxmap__store_u32_param(auxmap, fd_flags); + auxmap__store_u16_param(auxmap, fd_flags); /*=============================== COLLECT PARAMETERS ===========================*/ diff --git a/driver/ppm_fillers.c b/driver/ppm_fillers.c index 7c63e70284..25b6f9367f 100644 --- a/driver/ppm_fillers.c +++ b/driver/ppm_fillers.c @@ -300,7 +300,7 @@ int f_sys_open_x(struct event_filler_arguments *args) int64_t retval; struct file *file = NULL; enum ppm_overlay ol; - int32_t fd_flags = 0; + int16_t fd_flags = 0; /* * fd @@ -2992,7 +2992,7 @@ int f_sys_creat_x(struct event_filler_arguments *args) int64_t retval; struct file *file = NULL; enum ppm_overlay ol; - int32_t fd_flags = 0; + int16_t fd_flags = 0; /* * fd @@ -3584,7 +3584,7 @@ int f_sys_openat_x(struct event_filler_arguments *args) int64_t retval; struct file *file = NULL; enum ppm_overlay ol; - int32_t fd_flags = 0; + int16_t fd_flags = 0; retval = (int64_t)syscall_get_return_value(current, args->regs); res = val_to_ring(args, retval, 0, false, 0); @@ -5028,7 +5028,7 @@ int f_sys_openat2_x(struct event_filler_arguments *args) int64_t retval; struct file *file = NULL; enum ppm_overlay ol; - int32_t fd_flags = 0; + int16_t fd_flags = 0; #ifdef __NR_openat2 struct open_how how; #endif @@ -5201,7 +5201,7 @@ int f_sys_open_by_handle_at_x(struct event_filler_arguments *args) int32_t mountfd = 0; struct file *file = NULL; enum ppm_overlay ol; - int32_t fd_flags = 0; + int16_t fd_flags = 0; /* Parameter 1: ret (type: PT_FD) */ retval = syscall_get_return_value(current, args->regs); diff --git a/userspace/libsinsp/parsers.cpp b/userspace/libsinsp/parsers.cpp index 6b9d509c4f..a221a16163 100644 --- a/userspace/libsinsp/parsers.cpp +++ b/userspace/libsinsp/parsers.cpp @@ -2569,7 +2569,7 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) uint16_t etype = evt->get_type(); uint32_t dev = 0; uint64_t ino = 0; - uint32_t fd_flags = 0; + uint16_t fd_flags = 0; bool lastevent_retrieved = false; if(evt->get_tinfo() == nullptr) @@ -2606,7 +2606,7 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) ino = evt->get_param(5)->as(); if (evt->get_num_params() > 6) { - fd_flags = evt->get_param(6)->as(); + fd_flags = evt->get_param(6)->as(); } } } @@ -2647,7 +2647,7 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) ino = evt->get_param(4)->as(); if (evt->get_num_params() > 5) { - fd_flags = evt->get_param(5)->as(); + fd_flags = evt->get_param(5)->as(); } } } @@ -2697,7 +2697,7 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) ino = evt->get_param(6)->as(); if (evt->get_num_params() > 7) { - fd_flags = evt->get_param(7)->as(); + fd_flags = evt->get_param(7)->as(); } } } @@ -2709,7 +2709,7 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) ino = evt->get_param(7)->as(); if (evt->get_num_params() > 8) { - fd_flags = evt->get_param(8)->as(); + fd_flags = evt->get_param(8)->as(); } } } @@ -2753,7 +2753,7 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) ino = evt->get_param(5)->as(); if (evt->get_num_params() > 6) { - fd_flags = evt->get_param(6)->as(); + fd_flags = evt->get_param(6)->as(); } } } From 80256d530ae79e3b05cb7e3e7b6210c32a71cc05 Mon Sep 17 00:00:00 2001 From: Eddy Duer Date: Thu, 8 Aug 2024 19:01:03 +0300 Subject: [PATCH 3/7] Overlay FS flags are now sent in existing flags parameter in the open syscall family Signed-off-by: Eddy Duer --- driver/bpf/fillers.h | 142 +++++++---------- driver/event_table.c | 8 +- driver/flags_table.c | 2 + .../syscall_dispatched_events/open.bpf.c | 38 +++-- .../open_by_handle_at.bpf.c | 22 ++- .../syscall_dispatched_events/openat.bpf.c | 39 +++-- .../syscall_dispatched_events/openat2.bpf.c | 38 +++-- driver/ppm_events_public.h | 3 + driver/ppm_fillers.c | 144 +++++++----------- userspace/libsinsp/parsers.cpp | 55 +++---- 10 files changed, 195 insertions(+), 296 deletions(-) diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index 2486ecb45f..3009ac2082 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -99,6 +99,10 @@ static __always_inline struct inode *get_file_inode(struct file *file) static __always_inline enum ppm_overlay get_overlay_layer(struct file *file) { + if (!file) + { + return PPM_NOT_OVERLAY_FS; + } struct dentry* dentry = NULL; bpf_probe_read_kernel(&dentry, sizeof(dentry), &file->f_path.dentry); struct super_block* sb = (struct super_block*)_READ(dentry->d_sb); @@ -404,7 +408,6 @@ FILLER(sys_open_x, true) long retval; int res; struct file *file = NULL; - unsigned short fd_flags = 0; /* Parameter 1: ret (type: PT_FD) */ retval = bpf_syscall_get_retval(data->ctx); @@ -416,11 +419,22 @@ FILLER(sys_open_x, true) res = bpf_val_to_ring(data, val); CHECK_RES(res); + bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); + /* Parameter 3: flags (type: PT_FLAGS32) */ val = bpf_syscall_get_argument(data, 1); flags = open_flags_to_scap(val); /* update flags if file is created*/ flags |= bpf_get_fd_fmode_created(retval); + enum ppm_overlay ol = get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + flags |= PPM_O_F_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + flags |= PPM_O_F_LOWER_LAYER; + } res = bpf_push_u32_to_ring(data, flags); CHECK_RES(res); @@ -430,30 +444,12 @@ FILLER(sys_open_x, true) res = bpf_push_u32_to_ring(data, mode); CHECK_RES(res); - bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); - /* Parameter 5: dev (type: PT_UINT32) */ res = bpf_push_u32_to_ring(data, (uint32_t)dev); CHECK_RES(res); /* Parameter 6: ino (type: PT_UINT64) */ - res = bpf_push_u64_to_ring(data, (uint64_t)ino); - CHECK_RES(res); - - /* Parameter 7: fd_flags (type: PT_FLAGS16) */ - if (likely(file)) - { - enum ppm_overlay ol = get_overlay_layer(file); - if (ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - } - return bpf_push_u16_to_ring(data, (uint16_t)fd_flags); + return bpf_push_u64_to_ring(data, (uint64_t)ino); } FILLER(sys_read_e, true) @@ -3215,7 +3211,6 @@ FILLER(sys_openat_x, true) int32_t fd; int res; struct file *file = NULL; - unsigned short fd_flags = 0; retval = bpf_syscall_get_retval(data->ctx); res = bpf_push_s64_to_ring(data, retval); @@ -3238,6 +3233,8 @@ FILLER(sys_openat_x, true) res = bpf_val_to_ring(data, val); CHECK_RES(res); + bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); + /* * Flags * Note that we convert them into the ppm portable representation before pushing them to the ring @@ -3246,6 +3243,15 @@ FILLER(sys_openat_x, true) flags = open_flags_to_scap(val); /* update flags if file is created*/ flags |= bpf_get_fd_fmode_created(retval); + enum ppm_overlay ol = get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + flags |= PPM_O_F_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + flags |= PPM_O_F_LOWER_LAYER; + } res = bpf_push_u32_to_ring(data, flags); CHECK_RES(res); @@ -3257,8 +3263,6 @@ FILLER(sys_openat_x, true) res = bpf_push_u32_to_ring(data, mode); CHECK_RES(res); - bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); - /* * Device */ @@ -3268,25 +3272,7 @@ FILLER(sys_openat_x, true) /* * Ino */ - res = bpf_push_u64_to_ring(data, ino); - CHECK_RES(res); - - /* - * fd_flags - */ - if (likely(file)) - { - enum ppm_overlay ol = get_overlay_layer(file); - if (ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - } - return bpf_push_u16_to_ring(data, (uint16_t)fd_flags); + return bpf_push_u64_to_ring(data, ino); } FILLER(sys_openat2_e, true) @@ -3368,7 +3354,6 @@ FILLER(sys_openat2_x, true) int32_t fd; int res; struct file *file = NULL; - unsigned short fd_flags = 0; #ifdef __NR_openat2 struct open_how how; #endif @@ -3411,12 +3396,23 @@ FILLER(sys_openat2_x, true) resolve = 0; #endif + bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); + /* * flags (extracted from open_how structure) * Note that we convert them into the ppm portable representation before pushing them to the ring */ /* update flags if file is created*/ flags |= bpf_get_fd_fmode_created(retval); + enum ppm_overlay ol = get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + flags |= PPM_O_F_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + flags |= PPM_O_F_LOWER_LAYER; + } res = bpf_push_u32_to_ring(data, flags); CHECK_RES(res); @@ -3434,8 +3430,6 @@ FILLER(sys_openat2_x, true) res = bpf_push_u32_to_ring(data, resolve); CHECK_RES(res); - bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); - /* * dev */ @@ -3445,31 +3439,15 @@ FILLER(sys_openat2_x, true) /* * ino */ - res = bpf_push_u64_to_ring(data, ino); - CHECK_RES(res); - - /* - * fd_flags - */ - if (likely(file)) - { - enum ppm_overlay ol = get_overlay_layer(file); - if (ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - } - return bpf_push_u16_to_ring(data, (uint16_t)fd_flags); + return bpf_push_u64_to_ring(data, ino); } FILLER(sys_open_by_handle_at_x, true) { - /* Parameter 1: ret (type: PT_FD) */ long retval = bpf_syscall_get_retval(data->ctx); + struct file *file = bpf_fget(retval); + + /* Parameter 1: ret (type: PT_FD) */ int res = bpf_push_s64_to_ring(data, retval); CHECK_RES(res); @@ -3490,6 +3468,15 @@ FILLER(sys_open_by_handle_at_x, true) flags = (uint32_t)open_flags_to_scap(flags); /* update flags if file is created*/ flags |= bpf_get_fd_fmode_created(retval); + enum ppm_overlay ol = get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + flags |= PPM_O_F_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + flags |= PPM_O_F_LOWER_LAYER; + } res = bpf_val_to_ring(data, flags); CHECK_RES(res); @@ -3509,12 +3496,7 @@ FILLER(sys_open_by_handle_at_x, true) CHECK_RES(res); /* Parameter 6: ino (type: PT_UINT64) */ - res = bpf_push_u64_to_ring(data, 0); - CHECK_RES(res); - - /* Parameter 7: fd_flags (type: PT_FLAGS16) */ - return bpf_push_u16_to_ring(data, 0); - + return bpf_push_u64_to_ring(data, 0); } FILLER(open_by_handle_at_x_extra_tail_1, true) @@ -3548,23 +3530,7 @@ FILLER(open_by_handle_at_x_extra_tail_1, true) CHECK_RES(res); /* Parameter 6: ino (type: PT_UINT64) */ - res = bpf_push_u64_to_ring(data, ino); - CHECK_RES(res); - - /* Parameter 7: fd_flags (type: PT_FLAGS16) */ - if (likely(f)) - { - enum ppm_overlay ol = get_overlay_layer(f); - if (ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - } - return bpf_push_u16_to_ring(data, (uint16_t)fd_flags); + return bpf_push_u64_to_ring(data, ino); } FILLER(sys_io_uring_setup_x, true) diff --git a/driver/event_table.c b/driver/event_table.c index aa661e64a2..1e8cf966fc 100644 --- a/driver/event_table.c +++ b/driver/event_table.c @@ -53,7 +53,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_GENERIC_E] = {"syscall", EC_OTHER | EC_SYSCALL, EF_NONE, 2, {{"ID", PT_SYSCALLID, PF_DEC}, {"nativeID", PT_UINT16, PF_DEC} } }, [PPME_GENERIC_X] = {"syscall", EC_OTHER | EC_SYSCALL, EF_NONE, 1, {{"ID", PT_SYSCALLID, PF_DEC} } }, [PPME_SYSCALL_OPEN_E] = {"open", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 3, {{"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT} } }, - [PPME_SYSCALL_OPEN_X] = {"open", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 7, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_FLAGS16, PF_HEX} } }, + [PPME_SYSCALL_OPEN_X] = {"open", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, [PPME_SYSCALL_CLOSE_E] = {"close", EC_IO_OTHER | EC_SYSCALL, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } }, [PPME_SYSCALL_CLOSE_X] = {"close", EC_IO_OTHER | EC_SYSCALL, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_ERRNO, PF_DEC} } }, [PPME_SYSCALL_READ_E] = {"read", EC_IO_READ | EC_SYSCALL, EF_USES_FD | EF_READS_FROM_FD, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, @@ -359,7 +359,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_SYSCALL_MKDIRAT_E] = {"mkdirat", EC_FILE | EC_SYSCALL, EF_NONE, 0}, [PPME_SYSCALL_MKDIRAT_X] = {"mkdirat", EC_FILE | EC_SYSCALL, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"path", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"mode", PT_UINT32, PF_HEX} } }, [PPME_SYSCALL_OPENAT_2_E] = {"openat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(0)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT} } }, - [PPME_SYSCALL_OPENAT_2_X] = {"openat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 8, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_FLAGS16, PF_HEX} } }, + [PPME_SYSCALL_OPENAT_2_X] = {"openat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 7, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, [PPME_SYSCALL_LINK_2_E] = {"link", EC_FILE | EC_SYSCALL, EF_NONE, 0}, [PPME_SYSCALL_LINK_2_X] = {"link", EC_FILE | EC_SYSCALL, EF_NONE, 3, {{"res", PT_ERRNO, PF_DEC}, {"oldpath", PT_FSPATH, PF_NA}, {"newpath", PT_FSPATH, PF_NA} } }, [PPME_SYSCALL_LINKAT_2_E] = {"linkat", EC_FILE | EC_SYSCALL, EF_NONE, 0}, @@ -379,7 +379,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_CONTAINER_JSON_2_E] = {"container", EC_PROCESS | EC_METAEVENT, EF_MODIFIES_STATE | EF_LARGE_PAYLOAD, 1, {{"json", PT_CHARBUF, PF_NA} } }, /// TODO: do we need SKIPPARSERESET flag? [PPME_CONTAINER_JSON_2_X] = {"NA", EC_UNKNOWN, EF_UNUSED, 0}, [PPME_SYSCALL_OPENAT2_E] = {"openat2", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags} } }, - [PPME_SYSCALL_OPENAT2_X] = {"openat2", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 9, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_FLAGS16, PF_HEX} } }, + [PPME_SYSCALL_OPENAT2_X] = {"openat2", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 8, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, [PPME_SYSCALL_MPROTECT_E] = {"mprotect", EC_MEMORY | EC_SYSCALL, EF_NONE, 3, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags} } }, [PPME_SYSCALL_MPROTECT_X] = {"mprotect", EC_MEMORY | EC_SYSCALL, EF_NONE, 1, {{"res", PT_ERRNO, PF_DEC} } }, [PPME_SYSCALL_EXECVEAT_E] = {"execveat", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE, 3, {{"dirfd", PT_FD, PF_DEC}, {"pathname", PT_FSRELPATH, PF_NA, DIRFD_PARAM(0)}, {"flags", PT_FLAGS32, PF_HEX, execveat_flags} } }, @@ -389,7 +389,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_SYSCALL_CLONE3_E] = {"clone3", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE, 0}, [PPME_SYSCALL_CLONE3_X] = {"clone3", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE, 21, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"vtid", PT_PID, PF_DEC}, {"vpid", PT_PID, PF_DEC}, {"pidns_init_start_ts", PT_UINT64, PF_DEC} } }, [PPME_SYSCALL_OPEN_BY_HANDLE_AT_E] = {"open_by_handle_at", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, - [PPME_SYSCALL_OPEN_BY_HANDLE_AT_X] = {"open_by_handle_at", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 7, {{"fd", PT_FD, PF_DEC}, {"mountfd", PT_FD, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"path", PT_FSPATH, PF_NA}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_FLAGS16, PF_HEX} } }, + [PPME_SYSCALL_OPEN_BY_HANDLE_AT_X] = {"open_by_handle_at", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"mountfd", PT_FD, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"path", PT_FSPATH, PF_NA}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, [PPME_SYSCALL_IO_URING_SETUP_E] = {"io_uring_setup", EC_IO_OTHER | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, [PPME_SYSCALL_IO_URING_SETUP_X] = {"io_uring_setup", EC_IO_OTHER | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 8, {{"res", PT_ERRNO, PF_DEC}, {"entries", PT_UINT32, PF_DEC}, {"sq_entries", PT_UINT32, PF_DEC},{"cq_entries", PT_UINT32, PF_DEC},{"flags", PT_FLAGS32, PF_HEX, io_uring_setup_flags},{"sq_thread_cpu", PT_UINT32, PF_DEC}, {"sq_thread_idle", PT_UINT32, PF_DEC},{"features", PT_FLAGS32, PF_HEX, io_uring_setup_feats}}}, [PPME_SYSCALL_IO_URING_ENTER_E] = {"io_uring_enter", EC_IO_OTHER | EC_SYSCALL, EF_NONE, 0}, diff --git a/driver/flags_table.c b/driver/flags_table.c index d4b37f4118..c91248b636 100644 --- a/driver/flags_table.c +++ b/driver/flags_table.c @@ -72,6 +72,8 @@ const struct ppm_name_value file_flags[] = { {"O_NONE", PPM_O_NONE}, {"O_TMPFILE", PPM_O_TMPFILE}, {"O_F_CREATED", PPM_O_F_CREATED}, + {"O_F_UPPER_LAYER", PPM_O_F_UPPER_LAYER}, + {"O_F_LOWER_LAYER", PPM_O_F_LOWER_LAYER}, {0, 0}, }; diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c index aaac0cd03d..74767c16e4 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c @@ -65,6 +65,15 @@ int BPF_PROG(open_x, /*=============================== COLLECT PARAMETERS ===========================*/ + dev_t dev = 0; + uint64_t ino = 0; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; + + if(ret > 0) + { + extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); + } + /* Parameter 1: ret (type: PT_FD) */ auxmap__store_s64_param(auxmap, ret); @@ -77,39 +86,26 @@ int BPF_PROG(open_x, uint32_t scap_flags = (uint32_t)open_flags_to_scap(flags); /* update scap flags if file is created */ scap_flags |= extract__fmode_created_from_fd(ret); + if(ol == PPM_OVERLAY_UPPER) + { + scap_flags |= PPM_O_F_UPPER_LAYER; + } + else if(ol == PPM_OVERLAY_LOWER) + { + scap_flags |= PPM_O_F_LOWER_LAYER; + } auxmap__store_u32_param(auxmap, scap_flags); /* Parameter 4: mode (type: PT_UINT32) */ unsigned long mode = extract__syscall_argument(regs, 2); auxmap__store_u32_param(auxmap, open_modes_to_scap(flags, mode)); - dev_t dev = 0; - uint64_t ino = 0; - enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; - uint16_t fd_flags = 0; - - if(ret > 0) - { - extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); - } - /* Parameter 5: dev (type: PT_UINT32) */ auxmap__store_u32_param(auxmap, dev); /* Parameter 6: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); - /* Parameter 7: fd_flags (type: PT_FLAGS16) */ - if(ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if(ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - auxmap__store_u16_param(auxmap, fd_flags); - /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c index 568a2a2b8a..5bf33b7a60 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c @@ -70,7 +70,16 @@ int BPF_PROG(open_by_handle_at_x, flags = (uint32_t)open_flags_to_scap(flags); /* update flags if file is created */ flags |= extract__fmode_created_from_fd(ret); - + struct file *f = extract__file_struct_from_fd(ret); + enum ppm_overlay ol = extract__overlay_layer(f); + if(ol == PPM_OVERLAY_UPPER) + { + flags |= PPM_O_F_UPPER_LAYER; + } + else if(ol == PPM_OVERLAY_LOWER) + { + flags |= PPM_O_F_LOWER_LAYER; + } auxmap__store_u32_param(auxmap, flags); /*=============================== COLLECT PARAMETERS ===========================*/ @@ -122,17 +131,6 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) /* Parameter 6: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); - /* Parameter 7: fd_flags (type: PT_FLAGS16) */ - if(ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if(ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - auxmap__store_u16_param(auxmap, fd_flags); - /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c index 87e5270f0f..7738143c70 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c @@ -73,6 +73,15 @@ int BPF_PROG(openat_x, /*=============================== COLLECT PARAMETERS ===========================*/ + dev_t dev = 0; + uint64_t ino = 0; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; + + if(ret > 0) + { + extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); + } + /* Parameter 1: fd (type: PT_FD) */ auxmap__store_s64_param(auxmap, ret); @@ -93,40 +102,26 @@ int BPF_PROG(openat_x, uint32_t scap_flags = (uint32_t)open_flags_to_scap(flags); /* update flags if file is created */ scap_flags |= extract__fmode_created_from_fd(ret); - + if(ol == PPM_OVERLAY_UPPER) + { + scap_flags |= PPM_O_F_UPPER_LAYER; + } + else if(ol == PPM_OVERLAY_LOWER) + { + scap_flags |= PPM_O_F_LOWER_LAYER; + } auxmap__store_u32_param(auxmap, scap_flags); /* Parameter 5: mode (type: PT_UINT32) */ unsigned long mode = extract__syscall_argument(regs, 3); auxmap__store_u32_param(auxmap, open_modes_to_scap(flags, mode)); - dev_t dev = 0; - uint64_t ino = 0; - enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; - uint16_t fd_flags = 0; - - if(ret > 0) - { - extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); - } - /* Parameter 6: dev (type: PT_UINT32) */ auxmap__store_u32_param(auxmap, dev); /* Parameter 7: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); - /* Parameter 8: fd_flags (type: PT_FLAGS16) */ - if(ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if(ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - auxmap__store_u16_param(auxmap, fd_flags); - /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c index e8928d6818..af14ab7a53 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c @@ -79,6 +79,15 @@ int BPF_PROG(openat2_x, /*=============================== COLLECT PARAMETERS ===========================*/ + dev_t dev = 0; + uint64_t ino = 0; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; + + if(ret > 0) + { + extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); + } + /* Parameter 1: fd (type: PT_FD) */ auxmap__store_s64_param(auxmap, ret); @@ -103,6 +112,14 @@ int BPF_PROG(openat2_x, uint32_t flags = open_flags_to_scap(how.flags); /* update flags if file is created */ flags |= extract__fmode_created_from_fd(ret); + if(ol == PPM_OVERLAY_UPPER) + { + flags |= PPM_O_F_UPPER_LAYER; + } + else if(ol == PPM_OVERLAY_LOWER) + { + flags |= PPM_O_F_LOWER_LAYER; + } auxmap__store_u32_param(auxmap, flags); @@ -112,33 +129,12 @@ int BPF_PROG(openat2_x, /* Parameter 6: resolve (type: PT_FLAGS32) */ auxmap__store_u32_param(auxmap, openat2_resolve_to_scap(how.resolve)); - dev_t dev = 0; - uint64_t ino = 0; - enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; - uint16_t fd_flags = 0; - - if(ret > 0) - { - extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); - } - /* Parameter 7: dev (type: PT_UINT32) */ auxmap__store_u32_param(auxmap, dev); /* Parameter 8: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); - /* Parameter 9: fd_flags (type: PT_FLAGS16) */ - if(ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if(ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - auxmap__store_u16_param(auxmap, fd_flags); - /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/ppm_events_public.h b/driver/ppm_events_public.h index 53f6a0fa03..d26e05460b 100644 --- a/driver/ppm_events_public.h +++ b/driver/ppm_events_public.h @@ -103,7 +103,10 @@ or GPL2.txt for full copies of the license. #define PPM_O_LARGEFILE (1 << 11) #define PPM_O_CLOEXEC (1 << 12) #define PPM_O_TMPFILE (1 << 13) +/* Flags added by syscall probe: */ #define PPM_O_F_CREATED (1 << 14) /* file created during the syscall */ +#define PPM_O_F_UPPER_LAYER (1 << 15) /* file is from upper layer */ +#define PPM_O_F_LOWER_LAYER (1 << 16) /* file is from upper layer */ /* * File modes diff --git a/driver/ppm_fillers.c b/driver/ppm_fillers.c index 25b6f9367f..51d9a4893b 100644 --- a/driver/ppm_fillers.c +++ b/driver/ppm_fillers.c @@ -300,7 +300,6 @@ int f_sys_open_x(struct event_filler_arguments *args) int64_t retval; struct file *file = NULL; enum ppm_overlay ol; - int16_t fd_flags = 0; /* * fd @@ -317,6 +316,8 @@ int f_sys_open_x(struct event_filler_arguments *args) res = val_to_ring(args, val, 0, true, 0); CHECK_RES(res); + get_fd_dev_ino_file(retval, &dev, &ino, &file); + /* * Flags * Note that we convert them into the ppm portable representation before pushing them to the ring @@ -325,6 +326,15 @@ int f_sys_open_x(struct event_filler_arguments *args) scap_flags = open_flags_to_scap(flags); /* update scap flags if file is created */ get_fd_fmode_created(retval, &scap_flags); + ol = ppm_get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + scap_flags |= PPM_O_F_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + scap_flags |= PPM_O_F_LOWER_LAYER; + } res = val_to_ring(args, scap_flags, 0, false, 0); CHECK_RES(res); @@ -335,8 +345,6 @@ int f_sys_open_x(struct event_filler_arguments *args) res = val_to_ring(args, open_modes_to_scap(flags, modes), 0, false, 0); CHECK_RES(res); - get_fd_dev_ino_file(retval, &dev, &ino, &file); - /* * dev */ @@ -349,24 +357,6 @@ int f_sys_open_x(struct event_filler_arguments *args) res = val_to_ring(args, ino, 0, false, 0); CHECK_RES(res); - /* - * fd_flags - */ - if (likely(file)) - { - ol = ppm_get_overlay_layer(file); - if (ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - } - res = val_to_ring(args, fd_flags, 0, false, 0); - CHECK_RES(res); - return add_sentinel(args); } @@ -3031,17 +3021,14 @@ int f_sys_creat_x(struct event_filler_arguments *args) /* * fd_flags */ - if (likely(file)) + ol = ppm_get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) { - ol = ppm_get_overlay_layer(file); - if (ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } + fd_flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + fd_flags |= PPM_FD_LOWER_LAYER; } res = val_to_ring(args, fd_flags, 0, false, 0); CHECK_RES(res); @@ -3584,7 +3571,6 @@ int f_sys_openat_x(struct event_filler_arguments *args) int64_t retval; struct file *file = NULL; enum ppm_overlay ol; - int16_t fd_flags = 0; retval = (int64_t)syscall_get_return_value(current, args->regs); res = val_to_ring(args, retval, 0, false, 0); @@ -3608,6 +3594,7 @@ int f_sys_openat_x(struct event_filler_arguments *args) res = val_to_ring(args, val, 0, true, 0); CHECK_RES(res); + get_fd_dev_ino_file(retval, &dev, &ino, &file); /* * Flags * Note that we convert them into the ppm portable representation before pushing them to the ring @@ -3616,6 +3603,15 @@ int f_sys_openat_x(struct event_filler_arguments *args) scap_flags = open_flags_to_scap(flags); /* update scap flags if file is created */ get_fd_fmode_created(retval, &scap_flags); + ol = ppm_get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + scap_flags |= PPM_O_F_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + scap_flags |= PPM_O_F_LOWER_LAYER; + } res = val_to_ring(args, scap_flags, 0, false, 0); CHECK_RES(res); /* @@ -3624,7 +3620,6 @@ int f_sys_openat_x(struct event_filler_arguments *args) syscall_get_arguments_deprecated(args, 3, 1, &modes); res = val_to_ring(args, open_modes_to_scap(flags, modes), 0, false, 0); CHECK_RES(res); - get_fd_dev_ino_file(retval, &dev, &ino, &file); /* * dev @@ -3637,24 +3632,6 @@ int f_sys_openat_x(struct event_filler_arguments *args) res = val_to_ring(args, ino, 0, false, 0); CHECK_RES(res); - /* - * fd_flags - */ - if (likely(file)) - { - ol = ppm_get_overlay_layer(file); - if (ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - } - res = val_to_ring(args, fd_flags, 0, false, 0); - CHECK_RES(res); - return add_sentinel(args); } @@ -5028,7 +5005,6 @@ int f_sys_openat2_x(struct event_filler_arguments *args) int64_t retval; struct file *file = NULL; enum ppm_overlay ol; - int16_t fd_flags = 0; #ifdef __NR_openat2 struct open_how how; #endif @@ -5073,12 +5049,24 @@ int f_sys_openat2_x(struct event_filler_arguments *args) mode = 0; resolve = 0; #endif + + get_fd_dev_ino_file(retval, &dev, &ino, &file); + /* * flags (extracted from open_how structure) * Note that we convert them into the ppm portable representation before pushing them to the ring */ /* update flags if file is created */ get_fd_fmode_created(retval, &flags); + ol = ppm_get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + flags |= PPM_O_F_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + flags |= PPM_O_F_LOWER_LAYER; + } res = val_to_ring(args, flags, 0, true, 0); CHECK_RES(res); @@ -5096,8 +5084,6 @@ int f_sys_openat2_x(struct event_filler_arguments *args) res = val_to_ring(args, resolve, 0, true, 0); CHECK_RES(res); - get_fd_dev_ino_file(retval, &dev, &ino, &file); - /* * dev */ @@ -5110,24 +5096,6 @@ int f_sys_openat2_x(struct event_filler_arguments *args) res = val_to_ring(args, ino, 0, false, 0); CHECK_RES(res); - /* - * fd_flags - */ - if (likely(file)) - { - ol = ppm_get_overlay_layer(file); - if (ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - } - res = val_to_ring(args, fd_flags, 0, false, 0); - CHECK_RES(res); - return add_sentinel(args); } @@ -5201,7 +5169,6 @@ int f_sys_open_by_handle_at_x(struct event_filler_arguments *args) int32_t mountfd = 0; struct file *file = NULL; enum ppm_overlay ol; - int16_t fd_flags = 0; /* Parameter 1: ret (type: PT_FD) */ retval = syscall_get_return_value(current, args->regs); @@ -5218,11 +5185,22 @@ int f_sys_open_by_handle_at_x(struct event_filler_arguments *args) res = val_to_ring(args, (int64_t)mountfd, 0, false, 0); CHECK_RES(res); + get_fd_dev_ino_file(retval, &dev, &ino, &file); + /* Parameter 3: flags (type: PT_FLAGS32) */ syscall_get_arguments_deprecated(args, 2, 1, &val); flags = open_flags_to_scap(val); /* update flags if file is created */ get_fd_fmode_created(retval, &flags); + ol = ppm_get_overlay_layer(file); + if (ol == PPM_OVERLAY_UPPER) + { + flags |= PPM_O_F_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + flags |= PPM_O_F_LOWER_LAYER; + } res = val_to_ring(args, flags, 0, false, 0); CHECK_RES(res); @@ -5249,8 +5227,6 @@ int f_sys_open_by_handle_at_x(struct event_filler_arguments *args) res = val_to_ring(args, (unsigned long)pathname, 0, false, 0); CHECK_RES(res); - get_fd_dev_ino_file(retval, &dev, &ino, &file); - /* Parameter 5: dev (type: PT_UINT32) */ res = val_to_ring(args, dev, 0, false, 0); CHECK_RES(res); @@ -5259,24 +5235,6 @@ int f_sys_open_by_handle_at_x(struct event_filler_arguments *args) res = val_to_ring(args, ino, 0, false, 0); CHECK_RES(res); - /* - * fd_flags - */ - if (likely(file)) - { - ol = ppm_get_overlay_layer(file); - if (ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } - } - res = val_to_ring(args, fd_flags, 0, false, 0); - CHECK_RES(res); - return add_sentinel(args); } diff --git a/userspace/libsinsp/parsers.cpp b/userspace/libsinsp/parsers.cpp index a221a16163..c8982154e6 100644 --- a/userspace/libsinsp/parsers.cpp +++ b/userspace/libsinsp/parsers.cpp @@ -2569,7 +2569,6 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) uint16_t etype = evt->get_type(); uint32_t dev = 0; uint64_t ino = 0; - uint16_t fd_flags = 0; bool lastevent_retrieved = false; if(evt->get_tinfo() == nullptr) @@ -2604,10 +2603,6 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) if (evt->get_num_params() > 5) { ino = evt->get_param(5)->as(); - if (evt->get_num_params() > 6) - { - fd_flags = evt->get_param(6)->as(); - } } } @@ -2623,11 +2618,10 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) { name = enter_evt_name; - // keep PPM_O_F_CREATED flag if present - if (flags & PPM_O_F_CREATED) - flags = enter_evt_flags | PPM_O_F_CREATED; - else - flags = enter_evt_flags; + // keep flags added by the syscall exit probe if present + uint32_t mask = ~(PPM_O_F_CREATED - 1); + uint32_t added_flags = flags & mask; + flags = enter_evt_flags | added_flags; } } @@ -2647,7 +2641,15 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) ino = evt->get_param(4)->as(); if (evt->get_num_params() > 5) { - fd_flags = evt->get_param(5)->as(); + uint16_t fd_flags = evt->get_param(5)->as(); + if (fd_flags & PPM_FD_UPPER_LAYER) + { + flags |= PPM_O_F_UPPER_LAYER; + } + else if (fd_flags & PPM_FD_LOWER_LAYER) + { + flags |= PPM_O_F_LOWER_LAYER; + } } } } @@ -2661,11 +2663,7 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) { name = enter_evt_name; - // keep PPM_O_F_CREATED flag if present - if (flags & PPM_O_F_CREATED) - flags = enter_evt_flags | PPM_O_F_CREATED; - else - flags = enter_evt_flags; + flags |= enter_evt_flags; } } @@ -2695,10 +2693,6 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) if (evt->get_num_params() > 6) { ino = evt->get_param(6)->as(); - if (evt->get_num_params() > 7) - { - fd_flags = evt->get_param(7)->as(); - } } } else if(etype == PPME_SYSCALL_OPENAT2_X && evt->get_num_params() > 6) @@ -2707,10 +2701,6 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) if (evt->get_num_params() > 7) { ino = evt->get_param(7)->as(); - if (evt->get_num_params() > 8) - { - fd_flags = evt->get_param(8)->as(); - } } } @@ -2727,11 +2717,10 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) { name = enter_evt_name; - // keep PPM_O_F_CREATED flag if present - if (flags & PPM_O_F_CREATED) - flags = enter_evt_flags | PPM_O_F_CREATED; - else - flags = enter_evt_flags; + // keep flags added by the syscall exit probe if present + uint32_t mask = ~(PPM_O_F_CREATED - 1); + uint32_t added_flags = flags & mask; + flags = enter_evt_flags | added_flags; dirfd = enter_evt_dirfd; } @@ -2751,10 +2740,6 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) if (evt->get_num_params() > 5) { ino = evt->get_param(5)->as(); - if (evt->get_num_params() > 6) - { - fd_flags = evt->get_param(6)->as(); - } } } @@ -2795,11 +2780,11 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) fdi->m_ino = ino; fdi->add_filename_raw(name); fdi->add_filename(fullpath); - if(fd_flags & PPM_FD_UPPER_LAYER) + if(flags & PPM_O_F_UPPER_LAYER) { fdi->set_overlay_upper(); } - if(fd_flags & PPM_FD_LOWER_LAYER) + if(flags & PPM_O_F_LOWER_LAYER) { fdi->set_overlay_lower(); } From 59c4e6280c418c2dfff490d9b6e8bf8a10f2ca7f Mon Sep 17 00:00:00 2001 From: Eddy Duer Date: Tue, 13 Aug 2024 12:09:35 +0300 Subject: [PATCH 4/7] Changes after code review #2 Signed-off-by: Eddy Duer --- driver/bpf/filler_helpers.h | 54 ++++++- driver/bpf/fillers.h | 152 ++++++------------ driver/event_table.c | 2 +- driver/flags_table.c | 16 +- .../syscall_dispatched_events/creat.bpf.c | 10 +- .../syscall_dispatched_events/open.bpf.c | 4 +- .../open_by_handle_at.bpf.c | 43 ++--- .../syscall_dispatched_events/openat.bpf.c | 4 +- .../syscall_dispatched_events/openat2.bpf.c | 4 +- driver/ppm_events_public.h | 21 ++- driver/ppm_fillers.c | 99 +++++++----- .../syscall_exit_suite/creat_x.cpp | 11 +- .../syscall_exit_suite/execve_x.cpp | 2 +- .../libscap/engine/savefile/scap_savefile.c | 9 ++ userspace/libscap/scap_savefile.c | 2 + userspace/libsinsp/parsers.cpp | 16 +- userspace/libsinsp/test/events_param.ut.cpp | 2 +- userspace/libsinsp/test/filterchecks/evt.cpp | 54 +++++++ .../libsinsp/test/sinsp_with_test_input.cpp | 4 +- .../libsinsp/test/sinsp_with_test_input.h | 2 +- 20 files changed, 308 insertions(+), 203 deletions(-) diff --git a/driver/bpf/filler_helpers.h b/driver/bpf/filler_helpers.h index 6e217d5e9a..b4086a7aae 100644 --- a/driver/bpf/filler_helpers.h +++ b/driver/bpf/filler_helpers.h @@ -35,6 +35,14 @@ enum read_memory KERNEL = 1, }; +static __always_inline struct inode *get_file_inode(struct file *file) +{ + if (file) { + return _READ(file->f_inode); + } + return NULL; +} + static __always_inline bool in_port_range(uint16_t port, uint16_t min, uint16_t max) { return port >= min && port <= max; @@ -301,20 +309,58 @@ static __always_inline void bpf_get_ino_from_fd(int fd, unsigned long *ino) *ino = _READ(inode->i_ino); } -static __always_inline void bpf_get_dev_ino_file_from_fd(int fd, unsigned long *dev, unsigned long *ino, struct file **file) +static __always_inline enum ppm_overlay get_overlay_layer(struct file *file) +{ + if (!file) + { + return PPM_NOT_OVERLAY_FS; + } + struct dentry* dentry = NULL; + bpf_probe_read_kernel(&dentry, sizeof(dentry), &file->f_path.dentry); + struct super_block* sb = (struct super_block*)_READ(dentry->d_sb); + unsigned long sb_magic = _READ(sb->s_magic); + + if(sb_magic != PPM_OVERLAYFS_SUPER_MAGIC) + { + return PPM_NOT_OVERLAY_FS; + } + + char *vfs_inode = (char *)_READ(dentry->d_inode); + struct dentry *upper_dentry = NULL; + bpf_probe_read_kernel(&upper_dentry, sizeof(upper_dentry), (char *)vfs_inode + sizeof(struct inode)); + if(!upper_dentry) + { + return PPM_OVERLAY_LOWER; + } + + struct inode *upper_ino = _READ(upper_dentry->d_inode); + if(_READ(upper_ino->i_ino) != 0) + { + return PPM_OVERLAY_UPPER; + } + else + { + return PPM_OVERLAY_LOWER; + } +} + +static __always_inline void bpf_get_dev_ino_overlay_from_fd(int fd, unsigned long *dev, unsigned long *ino, enum ppm_overlay *ol) { struct super_block *sb; struct inode *inode; dev_t kdev; + struct file *file; if (fd < 0) return; - *file = bpf_fget(fd); - if (!*file) + file = bpf_fget(fd); + if (!file) return; - inode = _READ((*file)->f_inode); + *ol = get_overlay_layer(file); + + inode = _READ(file->f_inode); if (!inode) return; diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index 3009ac2082..611ad784f6 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -89,49 +89,6 @@ static __always_inline int bpf_##x(void *ctx) \ \ static __always_inline int __bpf_##x(struct filler_data *data) \ -static __always_inline struct inode *get_file_inode(struct file *file) -{ - if (file) { - return _READ(file->f_inode); - } - return NULL; -} - -static __always_inline enum ppm_overlay get_overlay_layer(struct file *file) -{ - if (!file) - { - return PPM_NOT_OVERLAY_FS; - } - struct dentry* dentry = NULL; - bpf_probe_read_kernel(&dentry, sizeof(dentry), &file->f_path.dentry); - struct super_block* sb = (struct super_block*)_READ(dentry->d_sb); - unsigned long sb_magic = _READ(sb->s_magic); - - if(sb_magic != PPM_OVERLAYFS_SUPER_MAGIC) - { - return PPM_NOT_OVERLAY_FS; - } - - char *vfs_inode = (char *)_READ(dentry->d_inode); - struct dentry *upper_dentry = NULL; - bpf_probe_read_kernel(&upper_dentry, sizeof(upper_dentry), (char *)vfs_inode + sizeof(struct inode)); - if(!upper_dentry) - { - return PPM_OVERLAY_LOWER; - } - - struct inode *upper_ino = _READ(upper_dentry->d_inode); - if(_READ(upper_ino->i_ino) != 0) - { - return PPM_OVERLAY_UPPER; - } - else - { - return PPM_OVERLAY_LOWER; - } -} - FILLER_RAW(terminate_filler) { struct scap_bpf_per_cpu_state *state; @@ -407,7 +364,7 @@ FILLER(sys_open_x, true) unsigned long ino = 0; long retval; int res; - struct file *file = NULL; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; /* Parameter 1: ret (type: PT_FD) */ retval = bpf_syscall_get_retval(data->ctx); @@ -419,21 +376,20 @@ FILLER(sys_open_x, true) res = bpf_val_to_ring(data, val); CHECK_RES(res); - bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); + bpf_get_dev_ino_overlay_from_fd(retval, &dev, &ino, &ol); /* Parameter 3: flags (type: PT_FLAGS32) */ val = bpf_syscall_get_argument(data, 1); flags = open_flags_to_scap(val); /* update flags if file is created*/ flags |= bpf_get_fd_fmode_created(retval); - enum ppm_overlay ol = get_overlay_layer(file); if (ol == PPM_OVERLAY_UPPER) { - flags |= PPM_O_F_UPPER_LAYER; + flags |= PPM_FD_UPPER_LAYER; } else if (ol == PPM_OVERLAY_LOWER) { - flags |= PPM_O_F_LOWER_LAYER; + flags |= PPM_FD_LOWER_LAYER; } res = bpf_push_u32_to_ring(data, flags); CHECK_RES(res); @@ -3210,7 +3166,7 @@ FILLER(sys_openat_x, true) long retval; int32_t fd; int res; - struct file *file = NULL; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; retval = bpf_syscall_get_retval(data->ctx); res = bpf_push_s64_to_ring(data, retval); @@ -3233,7 +3189,7 @@ FILLER(sys_openat_x, true) res = bpf_val_to_ring(data, val); CHECK_RES(res); - bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); + bpf_get_dev_ino_overlay_from_fd(retval, &dev, &ino, &ol); /* * Flags @@ -3243,14 +3199,13 @@ FILLER(sys_openat_x, true) flags = open_flags_to_scap(val); /* update flags if file is created*/ flags |= bpf_get_fd_fmode_created(retval); - enum ppm_overlay ol = get_overlay_layer(file); if (ol == PPM_OVERLAY_UPPER) { - flags |= PPM_O_F_UPPER_LAYER; + flags |= PPM_FD_UPPER_LAYER; } else if (ol == PPM_OVERLAY_LOWER) { - flags |= PPM_O_F_LOWER_LAYER; + flags |= PPM_FD_LOWER_LAYER; } res = bpf_push_u32_to_ring(data, flags); CHECK_RES(res); @@ -3353,7 +3308,7 @@ FILLER(sys_openat2_x, true) long retval; int32_t fd; int res; - struct file *file = NULL; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; #ifdef __NR_openat2 struct open_how how; #endif @@ -3396,7 +3351,7 @@ FILLER(sys_openat2_x, true) resolve = 0; #endif - bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); + bpf_get_dev_ino_overlay_from_fd(retval, &dev, &ino, &ol); /* * flags (extracted from open_how structure) @@ -3404,14 +3359,13 @@ FILLER(sys_openat2_x, true) */ /* update flags if file is created*/ flags |= bpf_get_fd_fmode_created(retval); - enum ppm_overlay ol = get_overlay_layer(file); if (ol == PPM_OVERLAY_UPPER) { - flags |= PPM_O_F_UPPER_LAYER; + flags |= PPM_FD_UPPER_LAYER; } else if (ol == PPM_OVERLAY_LOWER) { - flags |= PPM_O_F_LOWER_LAYER; + flags |= PPM_FD_LOWER_LAYER; } res = bpf_push_u32_to_ring(data, flags); CHECK_RES(res); @@ -3445,7 +3399,6 @@ FILLER(sys_openat2_x, true) FILLER(sys_open_by_handle_at_x, true) { long retval = bpf_syscall_get_retval(data->ctx); - struct file *file = bpf_fget(retval); /* Parameter 1: ret (type: PT_FD) */ int res = bpf_push_s64_to_ring(data, retval); @@ -3460,26 +3413,6 @@ FILLER(sys_open_by_handle_at_x, true) res = bpf_push_s64_to_ring(data, (int64_t)mountfd); CHECK_RES(res); - /* Parameter 3: flags (type: PT_FLAGS32) */ - /* Here we need to use `bpf_val_to_ring` to - * fix verifier issues on Amazolinux2 (Kernel 4.14.309-231.529.amzn2.x86_64) - */ - uint32_t flags = (uint32_t)bpf_syscall_get_argument(data, 2); - flags = (uint32_t)open_flags_to_scap(flags); - /* update flags if file is created*/ - flags |= bpf_get_fd_fmode_created(retval); - enum ppm_overlay ol = get_overlay_layer(file); - if (ol == PPM_OVERLAY_UPPER) - { - flags |= PPM_O_F_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - flags |= PPM_O_F_LOWER_LAYER; - } - res = bpf_val_to_ring(data, flags); - CHECK_RES(res); - if(retval > 0) { bpf_tail_call(data->ctx, &tail_map, PPM_FILLER_open_by_handle_at_x_extra_tail_1); @@ -3487,6 +3420,12 @@ FILLER(sys_open_by_handle_at_x, true) return PPM_FAILURE_BUG; } + /* Parameter 3: flags (type: PT_FLAGS32) */ + uint32_t flags = (uint32_t)bpf_syscall_get_argument(data, 2); + flags = (uint32_t)open_flags_to_scap(flags); + res = bpf_val_to_ring(data, flags); + CHECK_RES(res); + /* Parameter 4: path (type: PT_FSPATH) */ res = bpf_push_empty_param(data); CHECK_RES(res); @@ -3502,12 +3441,10 @@ FILLER(sys_open_by_handle_at_x, true) FILLER(open_by_handle_at_x_extra_tail_1, true) { long retval = bpf_syscall_get_retval(data->ctx); - struct file *f = NULL; + struct file *f = bpf_fget(retval); unsigned long dev = 0; unsigned long ino = 0; - unsigned short fd_flags = 0; - - bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &f); + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; if(f == NULL) { @@ -3521,9 +3458,30 @@ FILLER(open_by_handle_at_x_extra_tail_1, true) return PPM_FAILURE_BUG; } + bpf_get_dev_ino_overlay_from_fd(retval, &dev, &ino, &ol); + + /* Parameter 3: flags (type: PT_FLAGS32) */ + /* Here we need to use `bpf_val_to_ring` to + * fix verifier issues on Amazolinux2 (Kernel 4.14.309-231.529.amzn2.x86_64) + */ + uint32_t flags = (uint32_t)bpf_syscall_get_argument(data, 2); + flags = (uint32_t)open_flags_to_scap(flags); + /* update flags if file is created*/ + flags |= bpf_get_fd_fmode_created(retval); + if (ol == PPM_OVERLAY_UPPER) + { + flags |= PPM_FD_UPPER_LAYER; + } + else if (ol == PPM_OVERLAY_LOWER) + { + flags |= PPM_FD_LOWER_LAYER; + } + int res = bpf_val_to_ring(data, flags); + CHECK_RES(res); + /* Parameter 4: path (type: PT_FSPATH) */ char* filepath = bpf_d_path_approx(data, &(f->f_path)); - int res = bpf_val_to_ring_mem(data,(unsigned long)filepath, KERNEL); + res = bpf_val_to_ring_mem(data,(unsigned long)filepath, KERNEL); /* Parameter 5: dev (type: PT_UINT32) */ res = bpf_push_u32_to_ring(data, dev); @@ -4611,8 +4569,8 @@ FILLER(sys_creat_x, true) unsigned long mode; long retval; int res; - struct file *file = NULL; - unsigned short fd_flags = 0; + enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; + unsigned short creat_flags = 0; retval = bpf_syscall_get_retval(data->ctx); res = bpf_push_s64_to_ring(data, retval); @@ -4633,7 +4591,7 @@ FILLER(sys_creat_x, true) res = bpf_push_u32_to_ring(data, mode); CHECK_RES(res); - bpf_get_dev_ino_file_from_fd(retval, &dev, &ino, &file); + bpf_get_dev_ino_overlay_from_fd(retval, &dev, &ino, &ol); /* * Device @@ -4648,21 +4606,17 @@ FILLER(sys_creat_x, true) CHECK_RES(res); /* - * fd_flags + * creat_flags */ - if (likely(file)) + if (ol == PPM_OVERLAY_UPPER) { - enum ppm_overlay ol = get_overlay_layer(file); - if (ol == PPM_OVERLAY_UPPER) - { - fd_flags |= PPM_FD_UPPER_LAYER; - } - else if (ol == PPM_OVERLAY_LOWER) - { - fd_flags |= PPM_FD_LOWER_LAYER; - } + creat_flags |= PPM_FD_UPPER_LAYER_CREAT; + } + else if (ol == PPM_OVERLAY_LOWER) + { + creat_flags |= PPM_FD_LOWER_LAYER_CREAT; } - return bpf_push_u16_to_ring(data, (uint16_t)fd_flags); + return bpf_push_u16_to_ring(data, (uint16_t)creat_flags); } FILLER(sys_pipe_x, true) diff --git a/driver/event_table.c b/driver/event_table.c index 1e8cf966fc..b530a70bf7 100644 --- a/driver/event_table.c +++ b/driver/event_table.c @@ -109,7 +109,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_SOCKET_ACCEPT4_E] = {"accept", EC_NET | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 1, {{"flags", PT_INT32, PF_HEX} } }, [PPME_SOCKET_ACCEPT4_X] = {"accept", EC_NET | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 3, {{"fd", PT_FD, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA}, {"queuepct", PT_UINT8, PF_DEC} } }, [PPME_SYSCALL_CREAT_E] = {"creat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 2, {{"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT} } }, - [PPME_SYSCALL_CREAT_X] = {"creat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"fd_flags", PT_FLAGS16, PF_HEX} } }, + [PPME_SYSCALL_CREAT_X] = {"creat", EC_FILE | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC}, {"creat_flags", PT_FLAGS16, PF_HEX, creat_flags} } }, [PPME_SYSCALL_PIPE_E] = {"pipe", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, [PPME_SYSCALL_PIPE_X] = {"pipe", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"fd1", PT_FD, PF_DEC}, {"fd2", PT_FD, PF_DEC}, {"ino", PT_UINT64, PF_DEC} } }, [PPME_SYSCALL_EVENTFD_E] = {"eventfd", EC_IPC | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 2, {{"initval", PT_UINT64, PF_DEC}, {"flags", PT_UINT32, PF_HEX} } }, diff --git a/driver/flags_table.c b/driver/flags_table.c index c91248b636..a187059f24 100644 --- a/driver/flags_table.c +++ b/driver/flags_table.c @@ -72,8 +72,14 @@ const struct ppm_name_value file_flags[] = { {"O_NONE", PPM_O_NONE}, {"O_TMPFILE", PPM_O_TMPFILE}, {"O_F_CREATED", PPM_O_F_CREATED}, - {"O_F_UPPER_LAYER", PPM_O_F_UPPER_LAYER}, - {"O_F_LOWER_LAYER", PPM_O_F_LOWER_LAYER}, + {"FD_UPPER_LAYER", PPM_FD_UPPER_LAYER}, + {"FD_LOWER_LAYER", PPM_FD_LOWER_LAYER}, + {0, 0}, +}; + +const struct ppm_name_value creat_flags[] = { + {"FD_UPPER_LAYER_CREAT", PPM_FD_UPPER_LAYER_CREAT}, + {"FD_LOWER_LAYER_CREAT", PPM_FD_LOWER_LAYER_CREAT}, {0, 0}, }; @@ -773,9 +779,3 @@ const struct ppm_name_value finit_module_flags[] = { {"MODULE_INIT_COMPRESSED_FILE", PPM_MODULE_INIT_COMPRESSED_FILE}, {0, 0}, }; - -const struct ppm_name_value fd_flags[] = { - {"FD_UPPER_LAYER", PPM_FD_UPPER_LAYER}, - {"FD_LOWER_LAYER", PPM_FD_LOWER_LAYER}, - {0, 0}, -}; diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c index 72748bef88..2801504810 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/creat.bpf.c @@ -75,7 +75,7 @@ int BPF_PROG(creat_x, dev_t dev = 0; uint64_t ino = 0; enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; - uint16_t fd_flags = 0; + uint16_t creat_flags = 0; if(ret > 0) { @@ -88,16 +88,16 @@ int BPF_PROG(creat_x, /* Parameter 5: ino (type: PT_UINT64) */ auxmap__store_u64_param(auxmap, ino); - /* Parameter 6: fd_flags (type: PT_FLAGS16) */ + /* Parameter 6: creat_flags (type: PT_FLAGS16) */ if(ol == PPM_OVERLAY_UPPER) { - fd_flags |= PPM_FD_UPPER_LAYER; + creat_flags |= PPM_FD_UPPER_LAYER_CREAT; } else if(ol == PPM_OVERLAY_LOWER) { - fd_flags |= PPM_FD_LOWER_LAYER; + creat_flags |= PPM_FD_LOWER_LAYER_CREAT; } - auxmap__store_u16_param(auxmap, fd_flags); + auxmap__store_u16_param(auxmap, creat_flags); /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c index 74767c16e4..756911ff94 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open.bpf.c @@ -88,11 +88,11 @@ int BPF_PROG(open_x, scap_flags |= extract__fmode_created_from_fd(ret); if(ol == PPM_OVERLAY_UPPER) { - scap_flags |= PPM_O_F_UPPER_LAYER; + scap_flags |= PPM_FD_UPPER_LAYER; } else if(ol == PPM_OVERLAY_LOWER) { - scap_flags |= PPM_O_F_LOWER_LAYER; + scap_flags |= PPM_FD_LOWER_LAYER; } auxmap__store_u32_param(auxmap, scap_flags); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c index 5bf33b7a60..e3eadab08b 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/open_by_handle_at.bpf.c @@ -65,23 +65,6 @@ int BPF_PROG(open_by_handle_at_x, } auxmap__store_s64_param(auxmap, (int64_t)mountfd); - /* Parameter 3: flags (type: PT_FLAGS32) */ - uint32_t flags = (uint32_t)extract__syscall_argument(regs, 2); - flags = (uint32_t)open_flags_to_scap(flags); - /* update flags if file is created */ - flags |= extract__fmode_created_from_fd(ret); - struct file *f = extract__file_struct_from_fd(ret); - enum ppm_overlay ol = extract__overlay_layer(f); - if(ol == PPM_OVERLAY_UPPER) - { - flags |= PPM_O_F_UPPER_LAYER; - } - else if(ol == PPM_OVERLAY_LOWER) - { - flags |= PPM_O_F_LOWER_LAYER; - } - auxmap__store_u32_param(auxmap, flags); - /*=============================== COLLECT PARAMETERS ===========================*/ bpf_tail_call(ctx, &extra_event_prog_tail_table, T1_OPEN_BY_HANDLE_AT_X); @@ -94,7 +77,6 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) dev_t dev = 0; uint64_t ino = 0; enum ppm_overlay ol = PPM_NOT_OVERLAY_FS; - uint16_t fd_flags = 0; struct auxiliary_map *auxmap = auxmap__get(); if(!auxmap) @@ -104,7 +86,28 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) /*=============================== COLLECT PARAMETERS ===========================*/ - /* We collect the file path, dev and ino from the file descriptor only if it is valid */ + uint32_t flags = (uint32_t)extract__syscall_argument(regs, 2); + flags = (uint32_t)open_flags_to_scap(flags); + /* We collect dev, ino and overlay from the file descriptor only if it is valid */ + if(ret > 0) + { + extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); + + /* Parameter 3: flags (type: PT_FLAGS32) */ + /* update flags if file is created */ + flags |= extract__fmode_created_from_fd(ret); + if(ol == PPM_OVERLAY_UPPER) + { + flags |= PPM_FD_UPPER_LAYER; + } + else if(ol == PPM_OVERLAY_LOWER) + { + flags |= PPM_FD_LOWER_LAYER; + } + } + auxmap__store_u32_param(auxmap, flags); + + /* We collect the file path from the file descriptor only if it is valid */ if(ret > 0) { /* Parameter 4: path (type: PT_FSPATH) */ @@ -117,8 +120,6 @@ int BPF_PROG(t1_open_by_handle_at_x, struct pt_regs *regs, long ret) { auxmap__store_empty_param(auxmap); } - - extract__dev_ino_overlay_from_fd(ret, &dev, &ino, &ol); } else { diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c index 7738143c70..b9e400b9ac 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat.bpf.c @@ -104,11 +104,11 @@ int BPF_PROG(openat_x, scap_flags |= extract__fmode_created_from_fd(ret); if(ol == PPM_OVERLAY_UPPER) { - scap_flags |= PPM_O_F_UPPER_LAYER; + scap_flags |= PPM_FD_UPPER_LAYER; } else if(ol == PPM_OVERLAY_LOWER) { - scap_flags |= PPM_O_F_LOWER_LAYER; + scap_flags |= PPM_FD_LOWER_LAYER; } auxmap__store_u32_param(auxmap, scap_flags); diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c index af14ab7a53..ab33ece2ef 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/openat2.bpf.c @@ -114,11 +114,11 @@ int BPF_PROG(openat2_x, flags |= extract__fmode_created_from_fd(ret); if(ol == PPM_OVERLAY_UPPER) { - flags |= PPM_O_F_UPPER_LAYER; + flags |= PPM_FD_UPPER_LAYER; } else if(ol == PPM_OVERLAY_LOWER) { - flags |= PPM_O_F_LOWER_LAYER; + flags |= PPM_FD_LOWER_LAYER; } auxmap__store_u32_param(auxmap, flags); diff --git a/driver/ppm_events_public.h b/driver/ppm_events_public.h index d26e05460b..00da731076 100644 --- a/driver/ppm_events_public.h +++ b/driver/ppm_events_public.h @@ -105,8 +105,18 @@ or GPL2.txt for full copies of the license. #define PPM_O_TMPFILE (1 << 13) /* Flags added by syscall probe: */ #define PPM_O_F_CREATED (1 << 14) /* file created during the syscall */ -#define PPM_O_F_UPPER_LAYER (1 << 15) /* file is from upper layer */ -#define PPM_O_F_LOWER_LAYER (1 << 16) /* file is from upper layer */ +#define PPM_FD_UPPER_LAYER (1 << 15) /* file is from upper layer */ +#define PPM_FD_LOWER_LAYER (1 << 16) /* file is from upper layer */ + +/* + * creat flags + */ +/* These flags serve the same puropse as the flags PPM_FD_UPPER_LAYER and PPM_FD_LOWER_LAYER in the 'File flags' section. + * They are used in creat system call because it doesn't have a 'flags' parameter that can be used. + * This redifintion is needed because this 'creat_flags' parameter is 16 bits and the aforementioned flags are over 16 bits. + */ +#define PPM_FD_UPPER_LAYER_CREAT (1 << 0) /* file is from upper layer. Equivalent to PPM_FD_UPPER_LAYER */ +#define PPM_FD_LOWER_LAYER_CREAT (1 << 1) /* file is from upper layer. Equivalent to PPM_FD_LOWER_LAYER */ /* * File modes @@ -815,12 +825,6 @@ or GPL2.txt for full copies of the license. #define PPM_DELETE_MODULE_O_TRUNC (1 << 0) #define PPM_DELETE_MODULE_O_NONBLOCK (1 << 1) -/* - * FD flags - */ -#define PPM_FD_UPPER_LAYER (1 << 0) -#define PPM_FD_LOWER_LAYER (1 << 1) - /* * bpf_commands */ @@ -2197,6 +2201,7 @@ struct ppm_evt_hdr { extern const struct ppm_name_value socket_families[]; extern const struct ppm_name_value file_flags[]; +extern const struct ppm_name_value creat_flags[]; extern const struct ppm_name_value flock_flags[]; extern const struct ppm_name_value clone_flags[]; extern const struct ppm_name_value futex_operations[]; diff --git a/driver/ppm_fillers.c b/driver/ppm_fillers.c index 51d9a4893b..7490851aae 100644 --- a/driver/ppm_fillers.c +++ b/driver/ppm_fillers.c @@ -183,12 +183,47 @@ int f_sys_fstat_e(struct event_filler_arguments *args) return add_sentinel(args); } -static inline void get_fd_dev_ino_file(int64_t fd, uint32_t* dev, uint64_t* ino, struct file **file) +static inline void get_ino_from_fd(int64_t fd, uint64_t* ino) +{ + struct files_struct *files; + struct fdtable *fdt; + struct inode *inode; + struct file *file; + + if (fd < 0) + return; + + files = current->files; + if (unlikely(!files)) + return; + + spin_lock(&files->file_lock); + fdt = files_fdtable(files); + if (unlikely(fd > fdt->max_fds)) + goto out_unlock; + + file = fdt->fd[fd]; + if (unlikely(!file)) + goto out_unlock; + + inode = file_inode(file); + if (unlikely(!inode)) + goto out_unlock; + + *ino = inode->i_ino; + +out_unlock: + spin_unlock(&files->file_lock); + return; +} + +static inline void get_dev_ino_overlay_from_fd(int64_t fd, uint32_t* dev, uint64_t* ino, enum ppm_overlay *ol) { struct files_struct *files; struct fdtable *fdt; struct inode *inode; struct super_block *sb; + struct file *file; if (fd < 0) return; @@ -202,11 +237,13 @@ static inline void get_fd_dev_ino_file(int64_t fd, uint32_t* dev, uint64_t* ino, if (unlikely(fd > fdt->max_fds)) goto out_unlock; - *file = fdt->fd[fd]; - if (unlikely(!*file)) + file = fdt->fd[fd]; + if (unlikely(!file)) goto out_unlock; - inode = file_inode(*file); + *ol = ppm_get_overlay_layer(file); + + inode = file_inode(file); if (unlikely(!inode)) goto out_unlock; @@ -298,7 +335,6 @@ int f_sys_open_x(struct event_filler_arguments *args) uint64_t ino = 0; int res; int64_t retval; - struct file *file = NULL; enum ppm_overlay ol; /* @@ -316,7 +352,7 @@ int f_sys_open_x(struct event_filler_arguments *args) res = val_to_ring(args, val, 0, true, 0); CHECK_RES(res); - get_fd_dev_ino_file(retval, &dev, &ino, &file); + get_dev_ino_overlay_from_fd(retval, &dev, &ino, &ol); /* * Flags @@ -326,14 +362,13 @@ int f_sys_open_x(struct event_filler_arguments *args) scap_flags = open_flags_to_scap(flags); /* update scap flags if file is created */ get_fd_fmode_created(retval, &scap_flags); - ol = ppm_get_overlay_layer(file); if (ol == PPM_OVERLAY_UPPER) { - scap_flags |= PPM_O_F_UPPER_LAYER; + scap_flags |= PPM_FD_UPPER_LAYER; } else if (ol == PPM_OVERLAY_LOWER) { - scap_flags |= PPM_O_F_LOWER_LAYER; + scap_flags |= PPM_FD_LOWER_LAYER; } res = val_to_ring(args, scap_flags, 0, false, 0); CHECK_RES(res); @@ -2980,9 +3015,8 @@ int f_sys_creat_x(struct event_filler_arguments *args) uint64_t ino = 0; int res; int64_t retval; - struct file *file = NULL; enum ppm_overlay ol; - int16_t fd_flags = 0; + int16_t creat_flags = 0; /* * fd @@ -3004,7 +3038,7 @@ int f_sys_creat_x(struct event_filler_arguments *args) res = val_to_ring(args, open_modes_to_scap(O_CREAT, modes), 0, false, 0); CHECK_RES(res); - get_fd_dev_ino_file(retval, &dev, &ino, &file); + get_dev_ino_overlay_from_fd(retval, &dev, &ino, &ol); /* * dev @@ -3019,18 +3053,17 @@ int f_sys_creat_x(struct event_filler_arguments *args) CHECK_RES(res); /* - * fd_flags + * creat_flags */ - ol = ppm_get_overlay_layer(file); if (ol == PPM_OVERLAY_UPPER) { - fd_flags |= PPM_FD_UPPER_LAYER; + creat_flags |= PPM_FD_UPPER_LAYER_CREAT; } else if (ol == PPM_OVERLAY_LOWER) { - fd_flags |= PPM_FD_LOWER_LAYER; + creat_flags |= PPM_FD_LOWER_LAYER_CREAT; } - res = val_to_ring(args, fd_flags, 0, false, 0); + res = val_to_ring(args, creat_flags, 0, false, 0); CHECK_RES(res); return add_sentinel(args); @@ -3042,9 +3075,7 @@ int f_sys_pipe_x(struct event_filler_arguments *args) int64_t retval = 0; unsigned long val = 0; int pipefd[2] = {-1, -1}; - uint32_t dev = 0; uint64_t ino = 0; - struct file *file = NULL; /* Parameter 1: res (type: PT_ERRNO) */ retval = (int64_t)syscall_get_return_value(current, args->regs); @@ -3083,7 +3114,7 @@ int f_sys_pipe_x(struct event_filler_arguments *args) /* On success, pipe returns `0` */ if(retval == 0) { - get_fd_dev_ino_file(pipefd[0], &dev, &ino, &file); + get_ino_from_fd(pipefd[0], &ino); } /* Parameter 4: ino (type: PT_UINT64) */ @@ -3099,9 +3130,7 @@ int f_sys_pipe2_x(struct event_filler_arguments *args) int64_t retval = 0; unsigned long val = 0; int pipefd[2] = {-1, -1}; - uint32_t dev = 0; uint64_t ino = 0; - struct file *file = NULL; /* Parameter 1: res (type: PT_ERRNO) */ retval = (int64_t)syscall_get_return_value(current, args->regs); @@ -3140,7 +3169,7 @@ int f_sys_pipe2_x(struct event_filler_arguments *args) /* On success, pipe returns `0` */ if(retval == 0) { - get_fd_dev_ino_file(pipefd[0], &dev, &ino, &file); + get_ino_from_fd(pipefd[0], &ino); } /* Parameter 4: ino (type: PT_UINT64) */ @@ -3569,7 +3598,6 @@ int f_sys_openat_x(struct event_filler_arguments *args) int res; int32_t fd; int64_t retval; - struct file *file = NULL; enum ppm_overlay ol; retval = (int64_t)syscall_get_return_value(current, args->regs); @@ -3594,7 +3622,7 @@ int f_sys_openat_x(struct event_filler_arguments *args) res = val_to_ring(args, val, 0, true, 0); CHECK_RES(res); - get_fd_dev_ino_file(retval, &dev, &ino, &file); + get_dev_ino_overlay_from_fd(retval, &dev, &ino, &ol); /* * Flags * Note that we convert them into the ppm portable representation before pushing them to the ring @@ -3603,14 +3631,13 @@ int f_sys_openat_x(struct event_filler_arguments *args) scap_flags = open_flags_to_scap(flags); /* update scap flags if file is created */ get_fd_fmode_created(retval, &scap_flags); - ol = ppm_get_overlay_layer(file); if (ol == PPM_OVERLAY_UPPER) { - scap_flags |= PPM_O_F_UPPER_LAYER; + scap_flags |= PPM_FD_UPPER_LAYER; } else if (ol == PPM_OVERLAY_LOWER) { - scap_flags |= PPM_O_F_LOWER_LAYER; + scap_flags |= PPM_FD_LOWER_LAYER; } res = val_to_ring(args, scap_flags, 0, false, 0); CHECK_RES(res); @@ -5003,7 +5030,6 @@ int f_sys_openat2_x(struct event_filler_arguments *args) int res; int32_t fd; int64_t retval; - struct file *file = NULL; enum ppm_overlay ol; #ifdef __NR_openat2 struct open_how how; @@ -5050,7 +5076,7 @@ int f_sys_openat2_x(struct event_filler_arguments *args) resolve = 0; #endif - get_fd_dev_ino_file(retval, &dev, &ino, &file); + get_dev_ino_overlay_from_fd(retval, &dev, &ino, &ol); /* * flags (extracted from open_how structure) @@ -5058,14 +5084,13 @@ int f_sys_openat2_x(struct event_filler_arguments *args) */ /* update flags if file is created */ get_fd_fmode_created(retval, &flags); - ol = ppm_get_overlay_layer(file); if (ol == PPM_OVERLAY_UPPER) { - flags |= PPM_O_F_UPPER_LAYER; + flags |= PPM_FD_UPPER_LAYER; } else if (ol == PPM_OVERLAY_LOWER) { - flags |= PPM_O_F_LOWER_LAYER; + flags |= PPM_FD_LOWER_LAYER; } res = val_to_ring(args, flags, 0, true, 0); CHECK_RES(res); @@ -5167,7 +5192,6 @@ int f_sys_open_by_handle_at_x(struct event_filler_arguments *args) long retval = 0; char *pathname = NULL; int32_t mountfd = 0; - struct file *file = NULL; enum ppm_overlay ol; /* Parameter 1: ret (type: PT_FD) */ @@ -5185,21 +5209,20 @@ int f_sys_open_by_handle_at_x(struct event_filler_arguments *args) res = val_to_ring(args, (int64_t)mountfd, 0, false, 0); CHECK_RES(res); - get_fd_dev_ino_file(retval, &dev, &ino, &file); + get_dev_ino_overlay_from_fd(retval, &dev, &ino, &ol); /* Parameter 3: flags (type: PT_FLAGS32) */ syscall_get_arguments_deprecated(args, 2, 1, &val); flags = open_flags_to_scap(val); /* update flags if file is created */ get_fd_fmode_created(retval, &flags); - ol = ppm_get_overlay_layer(file); if (ol == PPM_OVERLAY_UPPER) { - flags |= PPM_O_F_UPPER_LAYER; + flags |= PPM_FD_UPPER_LAYER; } else if (ol == PPM_OVERLAY_LOWER) { - flags |= PPM_O_F_LOWER_LAYER; + flags |= PPM_FD_LOWER_LAYER; } res = val_to_ring(args, flags, 0, false, 0); CHECK_RES(res); diff --git a/test/drivers/test_suites/syscall_exit_suite/creat_x.cpp b/test/drivers/test_suites/syscall_exit_suite/creat_x.cpp index ef2cb176eb..2334aeab87 100644 --- a/test/drivers/test_suites/syscall_exit_suite/creat_x.cpp +++ b/test/drivers/test_suites/syscall_exit_suite/creat_x.cpp @@ -22,6 +22,7 @@ TEST(SyscallExit, creatX_success) uint32_t dev = (uint32_t)file_stat.st_dev; uint64_t inode = file_stat.st_ino; const bool is_ext4 = event_test::is_ext4_fs(fd); + uint16_t creat_flags = 0; /* Remove the file. */ syscall(__NR_close, fd); @@ -62,9 +63,12 @@ TEST(SyscallExit, creatX_success) /* Parameter 5: ino (type: PT_UINT64) */ evt_test->assert_numeric_param(5, (uint64_t)inode); + /* Parameter 6: creat_flags (type: PT_FLAGS16) */ + evt_test->assert_numeric_param(6, (uint16_t)creat_flags); + /*=============================== ASSERT PARAMETERS ===========================*/ - evt_test->assert_num_params_pushed(5); + evt_test->assert_num_params_pushed(6); } #endif /* defined(__NR_fstat) && defined(__NR_unlinkat) && defined(__NR_close) */ @@ -113,8 +117,11 @@ TEST(SyscallExit, creatX_failure) /* Parameter 5: ino (type: PT_UINT64) */ evt_test->assert_numeric_param(5, (uint64_t)0); + /* Parameter 6: creat_flags (type: PT_FLAGS16) */ + evt_test->assert_numeric_param(6, (uint16_t)0); + /*=============================== ASSERT PARAMETERS ===========================*/ - evt_test->assert_num_params_pushed(5); + evt_test->assert_num_params_pushed(6); } #endif diff --git a/test/drivers/test_suites/syscall_exit_suite/execve_x.cpp b/test/drivers/test_suites/syscall_exit_suite/execve_x.cpp index a8429d28a4..e3e07adb96 100644 --- a/test/drivers/test_suites/syscall_exit_suite/execve_x.cpp +++ b/test/drivers/test_suites/syscall_exit_suite/execve_x.cpp @@ -649,7 +649,7 @@ TEST(SyscallExit, execveX_not_upperlayer) /* PPM_EXE_WRITABLE is set when the user that executed a process can also write to the executable * file that is used to spawn it or is its owner or otherwise capable. */ - evt_test->assert_numeric_param(20, (uint32_t)PPM_EXE_WRITABLE, EQUAL); + evt_test->assert_numeric_param(20, (uint32_t)PPM_EXE_WRITABLE | PPM_EXE_LOWER_LAYER, EQUAL); /* Parameter 24: exe_file ino (type: PT_UINT64) */ evt_test->assert_numeric_param(24, (uint64_t)1, GREATER_EQUAL); diff --git a/userspace/libscap/engine/savefile/scap_savefile.c b/userspace/libscap/engine/savefile/scap_savefile.c index d3ae6555a0..9261753ff9 100644 --- a/userspace/libscap/engine/savefile/scap_savefile.c +++ b/userspace/libscap/engine/savefile/scap_savefile.c @@ -119,6 +119,7 @@ static int32_t scap_read_proclist(scap_reader_t* r, uint32_t block_length, uint3 tinfo.cap_permitted = 0; tinfo.cap_effective = 0; tinfo.exe_upper_layer = false; + tinfo.exe_lower_layer = false; tinfo.exe_ino = 0; tinfo.exe_ino_ctime = 0; tinfo.exe_ino_mtime = 0; @@ -683,6 +684,14 @@ static int32_t scap_read_proclist(scap_reader_t* r, uint32_t block_length, uint3 subreadsize += readsize; } + // exe_lower_layer + if(sub_len && (subreadsize + sizeof(uint8_t)) <= sub_len) + { + readsize = r->read(r, &(tinfo.exe_lower_layer), sizeof(uint8_t)); + CHECK_READ_SIZE_ERR(readsize, sizeof(uint8_t), error); + subreadsize += readsize; + } + // exe_ino if(sub_len && (subreadsize + sizeof(uint64_t)) <= sub_len) { diff --git a/userspace/libscap/scap_savefile.c b/userspace/libscap/scap_savefile.c index 13919bd057..6bdde75e98 100644 --- a/userspace/libscap/scap_savefile.c +++ b/userspace/libscap/scap_savefile.c @@ -651,6 +651,7 @@ int32_t scap_write_proclist_entry_bufs(scap_dumper_t *d, struct scap_threadinfo sizeof(uint64_t) + // cap_permitted sizeof(uint64_t) + // cap_effective sizeof(uint8_t) + // exe_upper_layer + sizeof(uint8_t) + // exe_lower_layer sizeof(uint64_t) + // exe_ino sizeof(uint64_t) + // exe_ino_ctime sizeof(uint64_t) + // exe_ino_mtime @@ -697,6 +698,7 @@ int32_t scap_write_proclist_entry_bufs(scap_dumper_t *d, struct scap_threadinfo scap_dump_write(d, &(tinfo->cap_permitted), sizeof(uint64_t)) != sizeof(uint64_t) || scap_dump_write(d, &(tinfo->cap_effective), sizeof(uint64_t)) != sizeof(uint64_t) || scap_dump_write(d, &(tinfo->exe_upper_layer), sizeof(uint8_t)) != sizeof(uint8_t) || + scap_dump_write(d, &(tinfo->exe_lower_layer), sizeof(uint8_t)) != sizeof(uint8_t) || scap_dump_write(d, &(tinfo->exe_ino), sizeof(uint64_t)) != sizeof(uint64_t) || scap_dump_write(d, &(tinfo->exe_ino_ctime), sizeof(uint64_t)) != sizeof(uint64_t) || scap_dump_write(d, &(tinfo->exe_ino_mtime), sizeof(uint64_t)) != sizeof(uint64_t) || diff --git a/userspace/libsinsp/parsers.cpp b/userspace/libsinsp/parsers.cpp index c8982154e6..589315c51f 100644 --- a/userspace/libsinsp/parsers.cpp +++ b/userspace/libsinsp/parsers.cpp @@ -2641,14 +2641,16 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) ino = evt->get_param(4)->as(); if (evt->get_num_params() > 5) { - uint16_t fd_flags = evt->get_param(5)->as(); - if (fd_flags & PPM_FD_UPPER_LAYER) + uint16_t creat_flags = evt->get_param(5)->as(); + // creat is a special case becuase it has no flags parameter, so the layer info bits arrive from probe + // in a separate creat_flags parameter and flags need to be constructed from it + if (creat_flags & PPM_FD_UPPER_LAYER_CREAT) { - flags |= PPM_O_F_UPPER_LAYER; + flags |= PPM_FD_UPPER_LAYER; } - else if (fd_flags & PPM_FD_LOWER_LAYER) + else if (creat_flags & PPM_FD_LOWER_LAYER_CREAT) { - flags |= PPM_O_F_LOWER_LAYER; + flags |= PPM_FD_LOWER_LAYER; } } } @@ -2780,11 +2782,11 @@ void sinsp_parser::parse_open_openat_creat_exit(sinsp_evt *evt) fdi->m_ino = ino; fdi->add_filename_raw(name); fdi->add_filename(fullpath); - if(flags & PPM_O_F_UPPER_LAYER) + if(flags & PPM_FD_UPPER_LAYER) { fdi->set_overlay_upper(); } - if(flags & PPM_O_F_LOWER_LAYER) + if(flags & PPM_FD_LOWER_LAYER) { fdi->set_overlay_lower(); } diff --git a/userspace/libsinsp/test/events_param.ut.cpp b/userspace/libsinsp/test/events_param.ut.cpp index 103e45a831..9dcb30f814 100644 --- a/userspace/libsinsp/test/events_param.ut.cpp +++ b/userspace/libsinsp/test/events_param.ut.cpp @@ -186,7 +186,7 @@ TEST_F(sinsp_with_test_input, filename_toctou) fd = 4; add_event(increasing_ts(), 2, PPME_SYSCALL_CREAT_E, 2, "/tmp/the_file", 0); - evt = add_event_advance_ts(increasing_ts(), 2, PPME_SYSCALL_CREAT_X, 5, fd, "/tmp/some_other_file", 0, 0, (uint64_t) 0); + evt = add_event_advance_ts(increasing_ts(), 2, PPME_SYSCALL_CREAT_X, 6, fd, "/tmp/some_other_file", 0, 0, (uint64_t) 0, (uint16_t) PPM_FD_LOWER_LAYER_CREAT); ASSERT_EQ(get_field_as_string(evt, "fd.name"), "/tmp/the_file"); } diff --git a/userspace/libsinsp/test/filterchecks/evt.cpp b/userspace/libsinsp/test/filterchecks/evt.cpp index c462bf6d6e..8cafa278fd 100644 --- a/userspace/libsinsp/test/filterchecks/evt.cpp +++ b/userspace/libsinsp/test/filterchecks/evt.cpp @@ -44,6 +44,60 @@ TEST_F(sinsp_with_test_input, EVT_FILTER_is_open_create) ASSERT_EQ(evt->get_fd_info()->m_openflags, PPM_O_RDWR | PPM_O_CREAT | PPM_O_F_CREATED); } +TEST_F(sinsp_with_test_input, EVT_FILTER_is_lower_layer) +{ + add_default_init_thread(); + + open_inspector(); + + std::string path = "/home/file.txt"; + int64_t fd = 3; + + // In the enter event we don't send the `PPM_O_F_CREATED` + sinsp_evt* evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_OPEN_E, 3, path.c_str(), + (uint32_t)PPM_O_RDONLY, (uint32_t)0); + + // The `fdinfo` is not populated in the enter event + ASSERT_FALSE(evt->get_fd_info()); + + evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_OPEN_X, 6, fd, path.c_str(), + (uint32_t)PPM_O_RDONLY | PPM_FD_LOWER_LAYER, (uint32_t)0, (uint32_t)5, + (uint64_t)123); + ASSERT_EQ(get_field_as_string(evt, "fd.is_lower_layer"), "true"); + ASSERT_EQ(get_field_as_string(evt, "fd.is_upper_layer"), "false"); + ASSERT_TRUE(evt->get_fd_info()); + + ASSERT_EQ(evt->get_fd_info()->is_overlay_lower(), true); + ASSERT_EQ(evt->get_fd_info()->is_overlay_upper(), false); +} + +TEST_F(sinsp_with_test_input, EVT_FILTER_is_upper_layer) +{ + add_default_init_thread(); + + open_inspector(); + + std::string path = "/home/file.txt"; + int64_t fd = 3; + + // In the enter event we don't send the `PPM_O_F_CREATED` + sinsp_evt* evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_OPEN_E, 3, path.c_str(), + (uint32_t)PPM_O_RDONLY, (uint32_t)0); + + // The `fdinfo` is not populated in the enter event + ASSERT_FALSE(evt->get_fd_info()); + + evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_OPEN_X, 6, fd, path.c_str(), + (uint32_t)PPM_O_RDONLY | PPM_FD_UPPER_LAYER, (uint32_t)0, (uint32_t)5, + (uint64_t)123); + ASSERT_EQ(get_field_as_string(evt, "fd.is_lower_layer"), "false"); + ASSERT_EQ(get_field_as_string(evt, "fd.is_upper_layer"), "true"); + ASSERT_TRUE(evt->get_fd_info()); + + ASSERT_EQ(evt->get_fd_info()->is_overlay_lower(), false); + ASSERT_EQ(evt->get_fd_info()->is_overlay_upper(), true); +} + TEST_F(sinsp_with_test_input, EVT_FILTER_rawarg_int) { add_default_init_thread(); diff --git a/userspace/libsinsp/test/sinsp_with_test_input.cpp b/userspace/libsinsp/test/sinsp_with_test_input.cpp index 6bfe0b5a4b..e06781eb21 100644 --- a/userspace/libsinsp/test/sinsp_with_test_input.cpp +++ b/userspace/libsinsp/test/sinsp_with_test_input.cpp @@ -323,7 +323,8 @@ scap_threadinfo sinsp_with_test_input::create_threadinfo( uint64_t cap_permitted, uint64_t cap_inheritable, uint64_t cap_effective, uint32_t vmsize_kb, uint32_t vmrss_kb, uint32_t vmswap_kb, uint64_t pfmajor, uint64_t pfminor, const std::vector& cgroups, const std::string& root, - int filtered_out, uint32_t tty, uint32_t loginuid, bool exe_upper_layer, bool exe_from_memfd) + int filtered_out, uint32_t tty, uint32_t loginuid, bool exe_upper_layer, bool exe_lower_layer, + bool exe_from_memfd) { scap_threadinfo tinfo = {}; @@ -352,6 +353,7 @@ scap_threadinfo sinsp_with_test_input::create_threadinfo( tinfo.tty = tty; tinfo.loginuid = loginuid; tinfo.exe_upper_layer = exe_upper_layer; + tinfo.exe_lower_layer = exe_lower_layer; tinfo.exe_from_memfd = exe_from_memfd; std::string argsv; diff --git a/userspace/libsinsp/test/sinsp_with_test_input.h b/userspace/libsinsp/test/sinsp_with_test_input.h index 1fa53a532a..fad9551355 100644 --- a/userspace/libsinsp/test/sinsp_with_test_input.h +++ b/userspace/libsinsp/test/sinsp_with_test_input.h @@ -187,7 +187,7 @@ class sinsp_with_test_input : public ::testing::Test uint64_t cap_permitted = 0x1ffffffffff, uint64_t cap_inheritable = 0, uint64_t cap_effective = 0x1ffffffffff, uint32_t vmsize_kb = 10000, uint32_t vmrss_kb = 100, uint32_t vmswap_kb = 0, uint64_t pfmajor = 222, uint64_t pfminor = 22, const std::vector& cgroups = {}, const std::string& root = "/", - int filtered_out = 0, uint32_t tty = 0, uint32_t loginuid = UINT32_MAX, bool exe_upper_layer = false, bool exe_from_memfd = false); + int filtered_out = 0, uint32_t tty = 0, uint32_t loginuid = UINT32_MAX, bool exe_upper_layer = false, bool exe_lower_layer = false, bool exe_from_memfd = false); void add_default_init_thread(); void add_simple_thread(int64_t tid, int64_t pid, int64_t ptid, const std::string& comm = "random"); From 4d8a96c5058a3c025814f7587ed0b45790a1309d Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Tue, 27 Aug 2024 11:29:18 +0200 Subject: [PATCH 5/7] fix(scap): fix scap-file support Signed-off-by: Andrea Terzolo --- .../libscap/engine/savefile/scap_savefile.c | 18 +++++++++--------- userspace/libscap/scap_savefile.c | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/userspace/libscap/engine/savefile/scap_savefile.c b/userspace/libscap/engine/savefile/scap_savefile.c index 9261753ff9..1fbb0eae4e 100644 --- a/userspace/libscap/engine/savefile/scap_savefile.c +++ b/userspace/libscap/engine/savefile/scap_savefile.c @@ -119,11 +119,11 @@ static int32_t scap_read_proclist(scap_reader_t* r, uint32_t block_length, uint3 tinfo.cap_permitted = 0; tinfo.cap_effective = 0; tinfo.exe_upper_layer = false; - tinfo.exe_lower_layer = false; tinfo.exe_ino = 0; tinfo.exe_ino_ctime = 0; tinfo.exe_ino_mtime = 0; tinfo.exe_from_memfd = false; + tinfo.exe_lower_layer = false; // // len @@ -684,14 +684,6 @@ static int32_t scap_read_proclist(scap_reader_t* r, uint32_t block_length, uint3 subreadsize += readsize; } - // exe_lower_layer - if(sub_len && (subreadsize + sizeof(uint8_t)) <= sub_len) - { - readsize = r->read(r, &(tinfo.exe_lower_layer), sizeof(uint8_t)); - CHECK_READ_SIZE_ERR(readsize, sizeof(uint8_t), error); - subreadsize += readsize; - } - // exe_ino if(sub_len && (subreadsize + sizeof(uint64_t)) <= sub_len) { @@ -726,6 +718,14 @@ static int32_t scap_read_proclist(scap_reader_t* r, uint32_t block_length, uint3 tinfo.exe_from_memfd = (exe_from_memfd != 0); } + // exe_lower_layer + if(sub_len && (subreadsize + sizeof(uint8_t)) <= sub_len) + { + readsize = r->read(r, &(tinfo.exe_lower_layer), sizeof(uint8_t)); + CHECK_READ_SIZE_ERR(readsize, sizeof(uint8_t), error); + subreadsize += readsize; + } + // // All parsed. Add the entry to the table, or fire the notification callback // diff --git a/userspace/libscap/scap_savefile.c b/userspace/libscap/scap_savefile.c index 6bdde75e98..5e73a031db 100644 --- a/userspace/libscap/scap_savefile.c +++ b/userspace/libscap/scap_savefile.c @@ -651,11 +651,11 @@ int32_t scap_write_proclist_entry_bufs(scap_dumper_t *d, struct scap_threadinfo sizeof(uint64_t) + // cap_permitted sizeof(uint64_t) + // cap_effective sizeof(uint8_t) + // exe_upper_layer - sizeof(uint8_t) + // exe_lower_layer sizeof(uint64_t) + // exe_ino sizeof(uint64_t) + // exe_ino_ctime sizeof(uint64_t) + // exe_ino_mtime - sizeof(uint8_t)); // exe_from_memfd + sizeof(uint8_t) + // exe_from_memfd + sizeof(uint8_t)); // exe_lower_layer if(scap_dump_write(d, len, sizeof(uint32_t)) != sizeof(uint32_t) || scap_dump_write(d, &(tinfo->tid), sizeof(uint64_t)) != sizeof(uint64_t) || @@ -698,11 +698,11 @@ int32_t scap_write_proclist_entry_bufs(scap_dumper_t *d, struct scap_threadinfo scap_dump_write(d, &(tinfo->cap_permitted), sizeof(uint64_t)) != sizeof(uint64_t) || scap_dump_write(d, &(tinfo->cap_effective), sizeof(uint64_t)) != sizeof(uint64_t) || scap_dump_write(d, &(tinfo->exe_upper_layer), sizeof(uint8_t)) != sizeof(uint8_t) || - scap_dump_write(d, &(tinfo->exe_lower_layer), sizeof(uint8_t)) != sizeof(uint8_t) || scap_dump_write(d, &(tinfo->exe_ino), sizeof(uint64_t)) != sizeof(uint64_t) || scap_dump_write(d, &(tinfo->exe_ino_ctime), sizeof(uint64_t)) != sizeof(uint64_t) || scap_dump_write(d, &(tinfo->exe_ino_mtime), sizeof(uint64_t)) != sizeof(uint64_t) || - scap_dump_write(d, &(tinfo->exe_from_memfd), sizeof(uint8_t)) != sizeof(uint8_t)) + scap_dump_write(d, &(tinfo->exe_from_memfd), sizeof(uint8_t)) != sizeof(uint8_t) || + scap_dump_write(d, &(tinfo->exe_lower_layer), sizeof(uint8_t)) != sizeof(uint8_t)) { snprintf(d->m_lasterr, SCAP_LASTERR_SIZE, "error writing to file (2)"); return SCAP_FAILURE; From 4a6a0a0338a6779c1e63c9b98c520c03c6a8ffe7 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Tue, 27 Aug 2024 13:09:02 +0200 Subject: [PATCH 6/7] docs: add a comment Signed-off-by: Andrea Terzolo --- driver/bpf/fillers.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index 611ad784f6..803edd37ef 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -3413,7 +3413,7 @@ FILLER(sys_open_by_handle_at_x, true) res = bpf_push_s64_to_ring(data, (int64_t)mountfd); CHECK_RES(res); - if(retval > 0) + if(retval >= 0) { bpf_tail_call(data->ctx, &tail_map, PPM_FILLER_open_by_handle_at_x_extra_tail_1); bpf_printk("Can't tail call 'open_by_handle_at_x_extra_tail_1' filler\n"); @@ -3421,6 +3421,8 @@ FILLER(sys_open_by_handle_at_x, true) } /* Parameter 3: flags (type: PT_FLAGS32) */ + // If `retval < 0` we cannot retrieve the `struct file` and + // so we cannot retrieve the `OVERLAY` and the `O_F_CREATED` flags uint32_t flags = (uint32_t)bpf_syscall_get_argument(data, 2); flags = (uint32_t)open_flags_to_scap(flags); res = bpf_val_to_ring(data, flags); From a332c03d75e75b7435c78601f4a0e2492b92bb80 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Tue, 27 Aug 2024 16:38:21 +0200 Subject: [PATCH 7/7] fix(tests): fix e2e sinsp tests Signed-off-by: Andrea Terzolo --- .../test_db_program_spawned_process.py | 2 +- test/e2e/tests/test_event_generator/test_file_writes.py | 8 ++++++-- .../test_event_generator/test_read_sensitive_file.py | 2 +- .../test_event_generator/test_run_shell_untrusted.py | 4 ++-- .../test_event_generator/test_system_user_interactive.py | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/test/e2e/tests/test_event_generator/test_db_program_spawned_process.py b/test/e2e/tests/test_event_generator/test_db_program_spawned_process.py index e45c392227..278e6db35d 100644 --- a/test/e2e/tests/test_event_generator/test_db_program_spawned_process.py +++ b/test/e2e/tests/test_event_generator/test_db_program_spawned_process.py @@ -53,7 +53,7 @@ def test_db_program_spawned_process(sinsp, run_containers: dict): }, { "container.id": generator_id, - "evt.args": SinspField.regex_field(r'^res=0 exe=/bin/ls args=NULL tid=\d+\(ls\) pid=\d+\(ls\) ptid=\d+\(mysqld\) .* tty=0 pgid=1\(systemd\) loginuid=-1\(\\) flags=1\(EXE_WRITABLE\) cap_inheritable=0'), + "evt.args": SinspField.regex_field(r'^res=0 exe=/bin/ls args=NULL tid=\d+\(ls\) pid=\d+\(ls\) ptid=\d+\(mysqld\) .* tty=0 pgid=1\(systemd\) loginuid=-1\(\\) flags=9\(EXE_WRITABLE\|EXE_LOWER_LAYER\) cap_inheritable=0'), "evt.category": "process", "evt.num": SinspField.numeric_field(), "evt.time": SinspField.numeric_field(), diff --git a/test/e2e/tests/test_event_generator/test_file_writes.py b/test/e2e/tests/test_event_generator/test_file_writes.py index 607f887342..cac2a57f74 100644 --- a/test/e2e/tests/test_event_generator/test_file_writes.py +++ b/test/e2e/tests/test_event_generator/test_file_writes.py @@ -5,7 +5,11 @@ def create_expected_arg(directory: str) -> str: - return fr'^fd=3\({re.escape(directory)}\/created-by-event-generator\) dirfd=-100\(AT_FDCWD\) name={re.escape(directory)}\/created-by-event-generator flags=20742\(O_TRUNC\|O_CREAT\|O_WRONLY\|O_CLOEXEC\|O_F_CREATED\) mode=0755 dev=.* ino=\d+$' + return fr'^fd=3\({re.escape(directory)}\/created-by-event-generator\) dirfd=-100\(AT_FDCWD\) name={re.escape(directory)}\/created-by-event-generator flags=53510\(O_TRUNC\|O_CREAT\|O_WRONLY\|O_CLOEXEC\|O_F_CREATED\|FD_UPPER_LAYER\) mode=0755 dev=.* ino=\d+$' + +def create_expected_arg_for_dev() -> str: + # please note that `/dev` folder is not in the overlay filesystem inside the container but in the tmpfs so it won't have the `FD_UPPER_LAYER` flag. That's the reason why it needs a different regex. + return fr'^fd=3\(/dev/created-by-event-generator\) dirfd=-100\(AT_FDCWD\) name=/dev/created-by-event-generator flags=20742\(O_TRUNC\|O_CREAT\|O_WRONLY\|O_CLOEXEC\|O_F_CREATED\) mode=0755 dev=.* ino=\d+$' def generate_ids(parameters: list) -> list: @@ -29,7 +33,7 @@ def generate_ids(parameters: list) -> list: expected_args = [ create_expected_arg('/etc'), create_expected_arg('/bin'), - create_expected_arg('/dev'), + create_expected_arg_for_dev(), create_expected_arg('/var/lib/rpm') ] generator_tuples = zip(generator_containers, expected_args) diff --git a/test/e2e/tests/test_event_generator/test_read_sensitive_file.py b/test/e2e/tests/test_event_generator/test_read_sensitive_file.py index ea68eb928d..14723992cc 100644 --- a/test/e2e/tests/test_event_generator/test_read_sensitive_file.py +++ b/test/e2e/tests/test_event_generator/test_read_sensitive_file.py @@ -55,7 +55,7 @@ def test_read_sensitive_file(sinsp, run_containers: dict, expected_process: str) expected_events = [ { - "evt.args": SinspField.regex_field(r'fd=3\(/etc/shadow\) dirfd=-100\(AT_FDCWD\) name=/etc/shadow flags=4097\(O_RDONLY|O_CLOEXEC\) mode=0 dev=\W+ ino=\d+'), + "evt.args": SinspField.regex_field(r'fd=3\(/etc/shadow\) dirfd=-100\(AT_FDCWD\) name=/etc/shadow flags=69633\(O_RDONLY|O_CLOEXEC\|FD_LOWER_LAYER\) mode=0 dev=\W+ ino=\d+'), "evt.cpu": SinspField.numeric_field(), "evt.dir": "<", "evt.num": SinspField.numeric_field(), diff --git a/test/e2e/tests/test_event_generator/test_run_shell_untrusted.py b/test/e2e/tests/test_event_generator/test_run_shell_untrusted.py index ab0a8ae8d8..9f6d032c20 100644 --- a/test/e2e/tests/test_event_generator/test_run_shell_untrusted.py +++ b/test/e2e/tests/test_event_generator/test_run_shell_untrusted.py @@ -26,7 +26,7 @@ def test_run_shell_untrusted(sinsp, run_containers: dict): expected_events = [ { "container.id": generator_id, - "evt.args": SinspField.regex_field(r'^res=0 exe=\/tmp\/falco-event-generator\d+\/httpd args=--loglevel.info.run.\^helper.RunShell\$. tid=\d+\(httpd\) pid=\d+\(httpd\) ptid=\d+\(event-generator\) .* tty=0 pgid=\d+\(systemd\) loginuid=-1\(\\) flags=1\(EXE_WRITABLE\) cap_inheritable=0'), + "evt.args": SinspField.regex_field(r'^res=0 exe=\/tmp\/falco-event-generator\d+\/httpd args=--loglevel.info.run.\^helper.RunShell\$. tid=\d+\(httpd\) pid=\d+\(httpd\) ptid=\d+\(event-generator\) .* tty=0 pgid=\d+\(systemd\) loginuid=-1\(\\) flags=9\(EXE_WRITABLE\|EXE_LOWER_LAYER\) cap_inheritable=0'), "evt.category": "process", "evt.num": SinspField.numeric_field(), "evt.time": SinspField.numeric_field(), @@ -38,7 +38,7 @@ def test_run_shell_untrusted(sinsp, run_containers: dict): }, { "container.id": generator_id, - "evt.args": SinspField.regex_field(r'^res=0 exe=bash args=-c.ls > \/dev\/null. tid=\d+\(bash\) pid=\d+\(bash\) ptid=\d+\(httpd\) .* tty=0 pgid=\d+\(systemd\) loginuid=-1\(\\) flags=1\(EXE_WRITABLE\) cap_inheritable=0'), + "evt.args": SinspField.regex_field(r'^res=0 exe=bash args=-c.ls > \/dev\/null. tid=\d+\(bash\) pid=\d+\(bash\) ptid=\d+\(httpd\) .* tty=0 pgid=\d+\(systemd\) loginuid=-1\(\\) flags=9\(EXE_WRITABLE\|EXE_LOWER_LAYER\) cap_inheritable=0'), "evt.category": "process", "evt.num": SinspField.numeric_field(), "evt.time": SinspField.numeric_field(), diff --git a/test/e2e/tests/test_event_generator/test_system_user_interactive.py b/test/e2e/tests/test_event_generator/test_system_user_interactive.py index 723ba672f6..7993f968b9 100644 --- a/test/e2e/tests/test_event_generator/test_system_user_interactive.py +++ b/test/e2e/tests/test_event_generator/test_system_user_interactive.py @@ -27,7 +27,7 @@ def test_system_user_interactive(sinsp, run_containers: dict): expected_events = [ { "container.id": generator_id, - "evt.args": SinspField.regex_field(r'^res=0 exe=\/bin\/login args=NULL tid=\d+\(login\) pid=\d+\(login\) ptid=\d+\(event-generator\) .* pgid=\d+\(systemd\) loginuid=-1\(\\) flags=0 cap_inheritable=0 cap_permitted=0 cap_effective=0'), + "evt.args": SinspField.regex_field(r'^res=0 exe=\/bin\/login args=NULL tid=\d+\(login\) pid=\d+\(login\) ptid=\d+\(event-generator\) .* pgid=\d+\(systemd\) loginuid=-1\(\\) flags=8\(EXE_LOWER_LAYER\) cap_inheritable=0 cap_permitted=0 cap_effective=0'), "evt.category": "process", "evt.num": SinspField.numeric_field(), "evt.time": SinspField.numeric_field(),