Skip to content

Commit

Permalink
fix umount2 syscall flags type, add conversion helper function
Browse files Browse the repository at this point in the history
- change the flags (param 1) from u32 to s32
- add a userspace to scap flag conversion helper routine

Reported by: github issue falcosecurity#515

Signed-off-by: Ofer Heifetz <oheifetz@gmail.com>
  • Loading branch information
oheifetz committed Aug 11, 2023
1 parent b607089 commit 5a7df98
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 7 deletions.
4 changes: 2 additions & 2 deletions driver/bpf/fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_s32_to_ring(data, umount2_flags_to_scap(flags));
}

FILLER(sys_umount2_x, true)
Expand Down
2 changes: 1 addition & 1 deletion driver/modern_bpf/definitions/events_dimensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
#define UNSHARE_E_SIZE HEADER_LEN + sizeof(uint32_t) + PARAM_LEN
#define UNSHARE_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN
#define MOUNT_E_SIZE HEADER_LEN + sizeof(uint32_t) + PARAM_LEN
#define UMOUNT2_E_SIZE HEADER_LEN + sizeof(uint32_t) + PARAM_LEN
#define UMOUNT2_E_SIZE HEADER_LEN + sizeof(int32_t) + PARAM_LEN
#define UMOUNT_E_SIZE HEADER_LEN
#define LINK_E_SIZE HEADER_LEN
#define LINKAT_E_SIZE HEADER_LEN
Expand Down
11 changes: 11 additions & 0 deletions driver/modern_bpf/definitions/missing_definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
//////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
s32 flags = (s32)extract__syscall_argument(regs, 1);
ringbuf__store_s32(&ringbuf, umount2_flags_to_scap(flags));

/*=============================== COLLECT PARAMETERS ===========================*/

Expand Down
2 changes: 1 addition & 1 deletion driver/ppm_fillers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, (u64)umount2_flags_to_scap(val), 0, true, 0);
CHECK_RES(res);

return add_sentinel(args);
Expand Down
26 changes: 26 additions & 0 deletions driver/ppm_flag_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ or GPL2.txt for full copies of the license.
#ifdef __NR_io_uring_register
#include <uapi/linux/io_uring.h>
#endif
#ifdef __NR_umount2
#include <linux/fs.h>
#endif
#endif // ifndef UDIG

#ifndef __always_inline
Expand Down Expand Up @@ -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(unsigned long 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;
Expand Down
2 changes: 1 addition & 1 deletion test/drivers/test_suites/syscall_enter_suite/umount2_e.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ TEST(SyscallEnter, umount2E)
/*=============================== ASSERT PARAMETERS ===========================*/

/* Parameter 1: flags (type: PT_FLAGS32) */
evt_test->assert_numeric_param(1, (uint32_t)(PPM_MNT_FORCE | PPM_MNT_DETACH | PPM_MNT_EXPIRE | PPM_UMOUNT_NOFOLLOW));
evt_test->assert_numeric_param(1, (int32_t)(PPM_MNT_FORCE | PPM_MNT_DETACH | PPM_MNT_EXPIRE | PPM_UMOUNT_NOFOLLOW));

/*=============================== ASSERT PARAMETERS ===========================*/

Expand Down

0 comments on commit 5a7df98

Please sign in to comment.