diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index b2f05bdbf0..14ac24bd92 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -3494,6 +3494,41 @@ FILLER(sys_mlock_x, true) return res; } +FILLER(sys_mlock2_x, true) +{ + unsigned long val; + unsigned long retval; + unsigned long res; + unsigned long flags; + + retval = bpf_syscall_get_retval(data->ctx); + res = bpf_val_to_ring(data, retval); + if (res != PPM_SUCCESS) + return res; + /* + * addr + */ + val = bpf_syscall_get_argument(data, 0); + res = bpf_val_to_ring(data, val); + if (res != PPM_SUCCESS) + return res; + /* + * len + */ + val = bpf_syscall_get_argument(data, 1); + res = bpf_val_to_ring(data, val); + if (res != PPM_SUCCESS) + return res; + /* + * flags + */ + val = bpf_syscall_get_argument(data, 2); + flags = mlock2_flags_to_scap(val); + res = bpf_val_to_ring(data, flags); + + return res; +} + FILLER(sys_munlock_x, true) { unsigned long val; diff --git a/driver/event_table.c b/driver/event_table.c index fdb8abe946..63c85f1bdf 100644 --- a/driver/event_table.c +++ b/driver/event_table.c @@ -382,6 +382,8 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_SYSCALL_DUP_1_X */{"dup", EC_IO_OTHER, EF_CREATES_FD | EF_USES_FD | EF_MODIFIES_STATE, 2, {{"res", PT_FD, PF_DEC}, {"oldfd", PT_FD, PF_DEC} } }, /* PPME_SYSCALL_BPF_2_E */{"bpf", EC_OTHER, EF_CREATES_FD, 1, {{"cmd", PT_INT64, PF_DEC} } }, /* PPME_SYSCALL_BPF_2_X */{"bpf", EC_OTHER, EF_CREATES_FD, 1, { {"fd", PT_FD, PF_DEC} } }, + /* PPME_SYSCALL_MLOCK2_E */{"mlock2", EC_MEMORY, EF_DROP_SIMPLE_CONS, 0}, + /* PPME_SYSCALL_MLOCK2_X */{"mlock2", EC_MEMORY, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_ERRNO, PF_DEC}, {"addr", PT_UINT64, PF_HEX}, {"len", PT_UINT64, PF_DEC}, {"flags", PT_UINT32, PF_HEX, mlockall_flags}}}, /* NB: Starting from scap version 1.2, event types will no longer be changed when an event is modified, and the only kind of change permitted for pre-existent events is adding parameters. * New event types are allowed only for new syscalls or new internal events. * The number of parameters can be used to differentiate between event versions. diff --git a/driver/fillers_table.c b/driver/fillers_table.c index 9e5f0736c8..3e8d848e88 100644 --- a/driver/fillers_table.c +++ b/driver/fillers_table.c @@ -333,5 +333,7 @@ const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = { [PPME_SYSCALL_MUNLOCKALL_X] = {FILLER_REF(sys_munlockall_x)}, [PPME_SYSCALL_CAPSET_E] = {FILLER_REF(sys_empty)}, [PPME_SYSCALL_CAPSET_X] = {FILLER_REF(sys_capset_x)}, + [PPME_SYSCALL_MLOCK2_E] = {FILLER_REF(sys_empty)}, + [PPME_SYSCALL_MLOCK2_X] = {FILLER_REF(sys_mlock2_x)}, #endif /* WDIG */ }; diff --git a/driver/flags_table.c b/driver/flags_table.c index 70ad920c56..bed38f83b8 100644 --- a/driver/flags_table.c +++ b/driver/flags_table.c @@ -614,3 +614,8 @@ const struct ppm_name_value mlockall_flags[] = { {"MCL_ONFAULT", PPM_MLOCKALL_MCL_ONFAULT}, {0,0}, }; + +const struct ppm_name_value mlock2_flags[] = { + {"MLOCK_ONFAULT", PPM_MLOCK_ONFAULT}, + {0,0}, +}; diff --git a/driver/ppm_compat_unistd_32.h b/driver/ppm_compat_unistd_32.h index 15b712526d..121d87eaae 100644 --- a/driver/ppm_compat_unistd_32.h +++ b/driver/ppm_compat_unistd_32.h @@ -364,10 +364,11 @@ #define __NR_ia32_io_uring_setup 356 #define __NR_ia32_io_uring_enter 357 #define __NR_ia32_io_uring_register 358 +#define __NR_ia32_mlock2 359 #ifdef __KERNEL__ -#define NR_ia32_syscalls 359 +#define NR_ia32_syscalls 360 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/driver/ppm_events_public.h b/driver/ppm_events_public.h index 20a3da25b4..0baa77f2cf 100644 --- a/driver/ppm_events_public.h +++ b/driver/ppm_events_public.h @@ -688,6 +688,11 @@ or GPL2.txt for full copies of the license. #define PPM_MLOCKALL_MCL_FUTURE (1<<1) #define PPM_MLOCKALL_MCL_ONFAULT (1<<2) +/* + * Mlock2 flags + */ +#define PPM_MLOCK_ONFAULT (1<<0) + /* * SuS says limits have to be unsigned. * Which makes a ton more sense anyway. @@ -1149,7 +1154,9 @@ enum ppm_event_type { PPME_SYSCALL_DUP_1_X = 367, PPME_SYSCALL_BPF_2_E = 368, PPME_SYSCALL_BPF_2_X = 369, - PPM_EVENT_MAX = 370 + PPME_SYSCALL_MLOCK2_E = 370, + PPME_SYSCALL_MLOCK2_X = 371, + PPM_EVENT_MAX = 372 }; /*@}*/ @@ -1501,7 +1508,8 @@ enum ppm_syscall_code { PPM_SC_IO_URING_SETUP = 330, PPM_SC_IO_URING_ENTER = 331, PPM_SC_IO_URING_REGISTER = 332, - PPM_SC_MAX = 333, + PPM_SC_MLOCK2 = 333, + PPM_SC_MAX = 334, }; /* @@ -1742,6 +1750,7 @@ extern const struct ppm_name_value io_uring_setup_feats[]; extern const struct ppm_name_value io_uring_enter_flags[]; extern const struct ppm_name_value io_uring_register_opcodes[]; extern const struct ppm_name_value mlockall_flags[]; +extern const struct ppm_name_value mlock2_flags[]; extern const struct ppm_param_info sockopt_dynamic_param[]; extern const struct ppm_param_info ptrace_dynamic_param[]; extern const struct ppm_param_info bpf_dynamic_param[]; diff --git a/driver/ppm_fillers.c b/driver/ppm_fillers.c index 82f32a85e3..7138eddb70 100644 --- a/driver/ppm_fillers.c +++ b/driver/ppm_fillers.c @@ -5158,6 +5158,39 @@ int f_sys_mlock_x(struct event_filler_arguments *args) return add_sentinel(args); } +int f_sys_mlock2_x(struct event_filler_arguments *args) +{ + unsigned long val; + + int64_t retval = (int64_t)syscall_get_return_value(current, args->regs); + int res = val_to_ring(args, retval, 0, false, 0); + if (unlikely(res != PPM_SUCCESS)) + return res; + /* + * addr + */ + syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val); + res = val_to_ring(args, val, 0, true, 0); + if (unlikely(res != PPM_SUCCESS)) + return res; + /* + * len + */ + syscall_get_arguments_deprecated(current, args->regs, 1, 1, &val); + res = val_to_ring(args, val, 0, true, 0); + if (unlikely(res != PPM_SUCCESS)) + return res; + /* + * flags + */ + syscall_get_arguments_deprecated(current, args->regs, 2, 1, &val); + res = val_to_ring(args, mlock2_flags_to_scap(val), 0, true, 0); + if (unlikely(res != PPM_SUCCESS)) + return res; + + return add_sentinel(args); +} + int f_sys_munlock_x(struct event_filler_arguments *args) { unsigned long val; diff --git a/driver/ppm_fillers.h b/driver/ppm_fillers.h index 8d80f5d445..6057e8a367 100644 --- a/driver/ppm_fillers.h +++ b/driver/ppm_fillers.h @@ -132,6 +132,7 @@ or GPL2.txt for full copies of the license. FN(sched_prog_fork) \ FN(sched_prog_fork_2) \ FN(sched_prog_fork_3) \ + FN(sys_mlock2_x) \ FN(terminate_filler) #define FILLER_ENUM_FN(x) PPM_FILLER_##x, diff --git a/driver/ppm_flag_helpers.h b/driver/ppm_flag_helpers.h index acf7c8d632..e35bdf8000 100644 --- a/driver/ppm_flag_helpers.h +++ b/driver/ppm_flag_helpers.h @@ -1591,6 +1591,16 @@ static __always_inline u32 mlockall_flags_to_scap(unsigned long flags) return res; } +static __always_inline u32 mlock2_flags_to_scap(unsigned long flags) +{ + u32 res = 0; +#ifdef MLOCK_ONFAULT + if (flags & MLOCK_ONFAULT) + res |= PPM_MLOCK_ONFAULT; +#endif + return res; +} + static __always_inline u32 unlinkat_flags_to_scap(unsigned long flags) { u32 res = 0; diff --git a/driver/syscall_table.c b/driver/syscall_table.c index 29ca286713..dc4390f43f 100644 --- a/driver/syscall_table.c +++ b/driver/syscall_table.c @@ -430,6 +430,9 @@ const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE] = { #ifdef __NR_munlockall [__NR_munlockall - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MUNLOCKALL_E, PPME_SYSCALL_MUNLOCKALL_X}, #endif +#ifdef __NR_mlock2 + [__NR_mlock2 - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MLOCK2_E, PPME_SYSCALL_MLOCK2_X}, +#endif }; /* @@ -1108,6 +1111,9 @@ const enum ppm_syscall_code g_syscall_code_routing_table[SYSCALL_TABLE_SIZE] = { #ifdef __NR_open_by_handle_at [__NR_open_by_handle_at - SYSCALL_TABLE_ID0] = PPM_SC_OPEN_BY_HANDLE_AT, #endif +#ifdef __NR_mlock2 + [__NR_mlock2 - SYSCALL_TABLE_ID0] = PPM_SC_MLOCK2, +#endif }; #ifdef CONFIG_IA32_EMULATION @@ -1392,6 +1398,9 @@ const struct syscall_evt_pair g_syscall_ia32_table[SYSCALL_TABLE_SIZE] = { #ifdef __NR_ia32_munlockall [__NR_ia32_munlockall - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MUNLOCKALL_E, PPME_SYSCALL_MUNLOCKALL_X}, #endif +#ifdef __NR_ia32_mlock2 + [__NR_ia32_mlock2 - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MLOCK_E, PPME_SYSCALL_MUNLOCK_X}, +#endif }; /* @@ -1977,6 +1986,9 @@ const enum ppm_syscall_code g_syscall_ia32_code_routing_table[SYSCALL_TABLE_SIZE #ifdef __NR_ia32_open_by_handle_at [__NR_ia32_open_by_handle_at - SYSCALL_TABLE_ID0] = PPM_SC_OPEN_BY_HANDLE_AT, #endif +#ifdef __NR_ia32_mlock2 + [__NR_ia32_mlock2 - SYSCALL_TABLE_ID0] = PPM_SC_MLOCK2, +#endif }; #endif /* CONFIG_IA32_EMULATION */ diff --git a/userspace/libscap/syscall_info_table.c b/userspace/libscap/syscall_info_table.c index fc46059fff..e702a0a131 100644 --- a/userspace/libscap/syscall_info_table.c +++ b/userspace/libscap/syscall_info_table.c @@ -362,6 +362,7 @@ const struct ppm_syscall_desc g_syscall_info_table[PPM_SC_MAX] = { /*PPM_SC_IO_URING_SETUP*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_uring_setup" }, /*PPM_SC_IO_URING_ENTER*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_uring_enter" }, /*PPM_SC_IO_URING_REGISTER*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_uring_register" }, + /*PPM_SC_MLOCK2*/ {EC_MEMORY, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mlock2"}, /* mlock2 locks part of the calling process's virtual address space int RAM*/ }; bool validate_info_table_size()