From 87a8701852ce6fa9717ac620f4a4b88fbe9504f0 Mon Sep 17 00:00:00 2001 From: Ofer Heifetz Date: Mon, 17 Jul 2023 15:14:02 +0300 Subject: [PATCH] fix umount2 syscall flags type, add conversion helper function - change the flags (param 1) from u32 to s32 - add a userspace to scap flag conversion helper routine Reported by: github issue #515 Signed-off-by: Ofer Heifetz --- driver/bpf/fillers.h | 4 +-- .../definitions/missing_definitions.h | 11 ++++++++ .../syscall_dispatched_events/umount2.bpf.c | 4 +-- driver/ppm_fillers.c | 2 +- driver/ppm_flag_helpers.h | 26 +++++++++++++++++++ 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index d02cdbc8d1..e6cab9cea5 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -6214,8 +6214,8 @@ FILLER(sys_umount_x, true) FILLER(sys_umount2_e, true) { /* Parameter 1: flags (type: PT_FLAGS32) */ - u32 flags = (u32)bpf_syscall_get_argument(data, 1); - return bpf_push_u32_to_ring(data, flags); + int flags = (int)bpf_syscall_get_argument(data, 1); + return bpf_push_u32_to_ring(data, umount2_flags_to_scap(flags)); } FILLER(sys_umount2_x, true) diff --git a/driver/modern_bpf/definitions/missing_definitions.h b/driver/modern_bpf/definitions/missing_definitions.h index 538cd20fcd..fdc1361b2e 100644 --- a/driver/modern_bpf/definitions/missing_definitions.h +++ b/driver/modern_bpf/definitions/missing_definitions.h @@ -552,6 +552,17 @@ #define MAY_WRITE 0x00000002 #define MAY_READ 0x00000004 +////////////////////////// +// umount options +////////////////////////// + +/* `include/linux/fs.h` from kernel source tree. */ + +#define MNT_FORCE 0x00000001 /* Attempt to forcibily umount */ +#define MNT_DETACH 0x00000002 /* Just detach from the tree */ +#define MNT_EXPIRE 0x00000004 /* Mark for expiry */ +#define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */ + ////////////////////////// // lseek whence ////////////////////////// diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/umount2.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/umount2.bpf.c index a76d832068..7c5470f595 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/umount2.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/umount2.bpf.c @@ -26,8 +26,8 @@ int BPF_PROG(umount2_e, /*=============================== COLLECT PARAMETERS ===========================*/ /* Parameter 1: flags (type: PT_FLAGS32) */ - u32 flags = (u32)extract__syscall_argument(regs, 1); - ringbuf__store_u32(&ringbuf, flags); + int flags = (int)extract__syscall_argument(regs, 1); + ringbuf__store_u32(&ringbuf, umount2_flags_to_scap(flags)); /*=============================== COLLECT PARAMETERS ===========================*/ diff --git a/driver/ppm_fillers.c b/driver/ppm_fillers.c index 05ff7d70e7..881c22a573 100644 --- a/driver/ppm_fillers.c +++ b/driver/ppm_fillers.c @@ -7278,7 +7278,7 @@ int f_sys_umount2_e(struct event_filler_arguments *args) /* Parameter 1: flags (type: PT_FLAGS32) */ syscall_get_arguments_deprecated(args, 1, 1, &val); - res = val_to_ring(args, val, 0, true, 0); + res = val_to_ring(args, umount2_flags_to_scap(val), 0, true, 0); CHECK_RES(res); return add_sentinel(args); diff --git a/driver/ppm_flag_helpers.h b/driver/ppm_flag_helpers.h index 668f69b6a6..390d827894 100644 --- a/driver/ppm_flag_helpers.h +++ b/driver/ppm_flag_helpers.h @@ -34,6 +34,9 @@ or GPL2.txt for full copies of the license. #ifdef __NR_io_uring_register #include #endif +#ifdef __NR_umount2 +#include +#endif #endif // ifndef UDIG #ifndef __always_inline @@ -1828,6 +1831,29 @@ static __always_inline u32 chmod_mode_to_scap(unsigned long modes) return res; } +static __always_inline u32 umount2_flags_to_scap(int flags) +{ + u32 res = 0; + +#ifdef MNT_FORCE + if (flags & MNT_FORCE) + res |= PPM_MNT_FORCE; +#endif +#ifdef MNT_DETACH + if (flags & MNT_DETACH) + res |= PPM_MNT_DETACH; +#endif +#ifdef MNT_EXPIRE + if (flags & MNT_EXPIRE) + res |= PPM_MNT_EXPIRE; +#endif +#ifdef UMOUNT_NOFOLLOW + if (flags & UMOUNT_NOFOLLOW) + res |= PPM_UMOUNT_NOFOLLOW; +#endif + return res; +} + static __always_inline u32 fchownat_flags_to_scap(unsigned long flags) { u32 res = 0;