Skip to content

Commit

Permalink
feat(driver): support for mknod/mknodat syscall
Browse files Browse the repository at this point in the history
Signed-off-by: Roberto Scolaro <[email protected]>
  • Loading branch information
therealbobo committed Aug 1, 2023
1 parent 3a08024 commit bd2d62c
Show file tree
Hide file tree
Showing 19 changed files with 1,147 additions and 10 deletions.
54 changes: 54 additions & 0 deletions driver/bpf/fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -7106,4 +7106,58 @@ FILLER(sys_finit_module_x, true)
return bpf_push_u32_to_ring(data, finit_module_flags_to_scap(flags));
}

FILLER(sys_mknod_x, true)
{

/* Parameter 1: ret (type: PT_ERRNO) */
long retval = bpf_syscall_get_retval(data->ctx);
int res = bpf_push_s64_to_ring(data, retval);
CHECK_RES(res);

/* Parameter 2: path (type: PT_CHARBUF) */
unsigned long path_pointer = bpf_syscall_get_argument(data, 0);
res = bpf_val_to_ring(data, path_pointer);
CHECK_RES(res);

/* Parameter 3: mode (type: PT_MODE) */
u32 mode = bpf_syscall_get_argument(data, 1);
res = bpf_push_u32_to_ring(data, mknod_mode_to_scap(mode));
CHECK_RES(res);

/* Parameter 4: dev (type: PT_UINT32) */
u32 dev = bpf_syscall_get_argument(data, 2);
return bpf_push_u32_to_ring(data, dev);
}

FILLER(sys_mknodat_x, true)
{
unsigned long val;
s32 fd;

/* Parameter 1: ret (type: PT_ERRNO) */
long retval = bpf_syscall_get_retval(data->ctx);
int res = bpf_push_s64_to_ring(data, retval);
CHECK_RES(res);

/* Parameter 2: fd (type: PT_FD) */
fd = (s32)bpf_syscall_get_argument(data, 0);
if (fd == AT_FDCWD)
fd = PPM_AT_FDCWD;
res = bpf_push_s64_to_ring(data, (s64)fd);
CHECK_RES(res);

/* Parameter 3: path (type: PT_CHARBUF) */
val = bpf_syscall_get_argument(data, 1);
res = bpf_val_to_ring(data, val);
CHECK_RES(res);

/* Parameter 4: mode (type: PT_MODE) */
u32 mode = bpf_syscall_get_argument(data, 2);
res = bpf_push_u32_to_ring(data, mknod_mode_to_scap(mode));
CHECK_RES(res);

/* Parameter 5: dev (type: PT_UINT32) */
u32 dev = bpf_syscall_get_argument(data, 3);
return bpf_push_u32_to_ring(data, dev);
}
#endif
2 changes: 1 addition & 1 deletion driver/event_stats.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

/* These numbers must be updated when we add new events in the event table */
#define SYSCALL_EVENTS_NUM 366
#define SYSCALL_EVENTS_NUM 370
#define TRACEPOINT_EVENTS_NUM 6
#define METAEVENTS_NUM 20
#define PLUGIN_EVENTS_NUM 1
Expand Down
4 changes: 4 additions & 0 deletions driver/event_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,10 @@ const struct ppm_event_info g_event_info[] = {
[PPME_SYSCALL_INIT_MODULE_X] = {"init_module", EC_OTHER | EC_SYSCALL, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"img", PT_BYTEBUF, PF_NA}, {"length", PT_UINT64, PF_DEC}, {"uargs", PT_CHARBUF, PF_NA}}},
[PPME_SYSCALL_FINIT_MODULE_E] = {"finit_module", EC_OTHER | EC_SYSCALL, EF_NONE, 0},
[PPME_SYSCALL_FINIT_MODULE_X] = {"finit_module", EC_OTHER | EC_SYSCALL, EF_USES_FD | EF_READS_FROM_FD, 4, {{"res", PT_ERRNO, PF_DEC}, {"fd", PT_FD, PF_DEC}, {"uargs", PT_CHARBUF, PF_NA}, {"flags", PT_FLAGS32, PF_DEC}}},
[PPME_SYSCALL_MKNOD_E] = {"mknod", EC_OTHER | EC_SYSCALL, EF_NONE, 0},
[PPME_SYSCALL_MKNOD_X] = {"mknod", EC_OTHER | EC_SYSCALL, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_CHARBUF, PF_NA},{"mode", PT_MODE, PF_OCT, mknod_mode},{"dev", PT_UINT32, PF_DEC}}},
[PPME_SYSCALL_MKNODAT_E] = {"mknodat", EC_OTHER | EC_SYSCALL, EF_NONE, 0},
[PPME_SYSCALL_MKNODAT_X] = {"mknodat", EC_OTHER | EC_SYSCALL, EF_NONE, 5, {{"res", PT_ERRNO, PF_DEC}, {"dirfd", PT_FD, PF_DEC},{"path", PT_CHARBUF, PF_NA},{"mode", PT_MODE, PF_OCT, mknod_mode},{"dev", PT_UINT32, PF_DEC}}},
};

// We don't need this check in kmod (this source file is included during kmod compilation!)
Expand Down
6 changes: 5 additions & 1 deletion driver/fillers_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,5 +347,9 @@ const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = {
[PPME_SYSCALL_INIT_MODULE_E] = {FILLER_REF(sys_empty)},
[PPME_SYSCALL_INIT_MODULE_X] = {FILLER_REF(sys_init_module_x)},
[PPME_SYSCALL_FINIT_MODULE_E] = {FILLER_REF(sys_empty)},
[PPME_SYSCALL_FINIT_MODULE_X] = {FILLER_REF(sys_finit_module_x)}
[PPME_SYSCALL_FINIT_MODULE_X] = {FILLER_REF(sys_finit_module_x)},
[PPME_SYSCALL_MKNOD_E] = {FILLER_REF(sys_empty)},
[PPME_SYSCALL_MKNOD_X] = {FILLER_REF(sys_mknod_x)},
[PPME_SYSCALL_MKNODAT_E] = {FILLER_REF(sys_empty)},
[PPME_SYSCALL_MKNODAT_X] = {FILLER_REF(sys_mknodat_x)}
};
24 changes: 23 additions & 1 deletion driver/flags_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,4 +684,26 @@ const struct ppm_name_value memfd_create_flags[] = {
const struct ppm_name_value pidfd_open_flags[] = {
{"PIDFD_NONBLOCK", PPM_PIDFD_NONBLOCK},
{0,0},
};
};

const struct ppm_name_value mknod_mode[] = {
{"S_IXOTH", PPM_S_IXOTH},
{"S_IWOTH", PPM_S_IWOTH},
{"S_IROTH", PPM_S_IROTH},
{"S_IXGRP", PPM_S_IXGRP},
{"S_IWGRP", PPM_S_IWGRP},
{"S_IRGRP", PPM_S_IRGRP},
{"S_IXUSR", PPM_S_IXUSR},
{"S_IWUSR", PPM_S_IWUSR},
{"S_IRUSR", PPM_S_IRUSR},
{"S_ISVTX", PPM_S_ISVTX},
{"S_ISGID", PPM_S_ISGID},
{"S_ISUID", PPM_S_ISUID},
{"S_IFREG", PPM_S_IFREG},
{"S_IFCHR", PPM_S_IFCHR},
{"S_IFBLK", PPM_S_IFBLK},
{"S_IFIFO", PPM_S_IFIFO},
{"S_IFSOCK", PPM_S_IFSOCK},
{0, 0},
};

2 changes: 2 additions & 0 deletions driver/modern_bpf/definitions/events_dimensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@
#define PIDFD_OPEN_X_SIZE HEADER_LEN + sizeof(int64_t) * 2 + sizeof(uint32_t) + 3 * PARAM_LEN
#define INIT_MODULE_E_SIZE HEADER_LEN
#define FINIT_MODULE_E_SIZE HEADER_LEN
#define MKNOD_E_SIZE HEADER_LEN
#define MKNODAT_E_SIZE HEADER_LEN

/* Generic tracepoints events. */
#define SCHED_SWITCH_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint64_t) * 2 + sizeof(uint32_t) * 3 + PARAM_LEN * 6
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2023 The Falco Authors.
*
* This file is dual licensed under either the MIT or GPL 2. See MIT.txt
* or GPL2.txt for full copies of the license.
*/

#include <helpers/interfaces/fixed_size_event.h>
#include <helpers/interfaces/variable_size_event.h>

/*=============================== ENTER EVENT ===========================*/

SEC("tp_btf/sys_enter")
int BPF_PROG(mknod_e,
struct pt_regs *regs,
long id)
{
struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, ctx, MKNOD_E_SIZE, PPME_SYSCALL_MKNOD_E))
{
return 0;
}

ringbuf__store_event_header(&ringbuf);

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

// Here we have no parameters to collect.

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

ringbuf__submit_event(&ringbuf);

return 0;


}

/*=============================== ENTER EVENT ===========================*/

/*=============================== EXIT EVENT ===========================*/

SEC("tp_btf/sys_exit")
int BPF_PROG(mknod_x,
struct pt_regs *regs,
long ret)
{
struct auxiliary_map *auxmap = auxmap__get();
if(!auxmap)
{
return 0;
}

auxmap__preload_event_header(auxmap, PPME_SYSCALL_MKNOD_X);

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

/* Parameter 1: ret (type: PT_ERRNO) */
auxmap__store_s64_param(auxmap, ret);

/* Parameter 2: path (type: PT_CHARBUF) */
unsigned long path_pointer = extract__syscall_argument(regs, 0);
auxmap__store_charbuf_param(auxmap, path_pointer, MAX_PATH, USER);

/* Parameter 3: mode (type: PT_MODE) */
u32 mode = (u32)extract__syscall_argument(regs, 1);
auxmap__store_u32_param(auxmap,mknod_mode_to_scap(mode));

/* Parameter 4: dev (type: PT_UINT32) */
u32 dev = (u32)extract__syscall_argument(regs, 2);
auxmap__store_u32_param(auxmap, dev);


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

auxmap__finalize_event_header(auxmap);

auxmap__submit_event(auxmap, ctx);

return 0;
}

/*=============================== EXIT EVENT ===========================*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (C) 2023 The Falco Authors.
*
* This file is dual licensed under either the MIT or GPL 2. See MIT.txt
* or GPL2.txt for full copies of the license.
*/

#include <helpers/interfaces/fixed_size_event.h>
#include <helpers/interfaces/variable_size_event.h>

/*=============================== ENTER EVENT ===========================*/

SEC("tp_btf/sys_enter")
int BPF_PROG(mknodat_e,
struct pt_regs *regs,
long id)
{
struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, ctx, MKNODAT_E_SIZE, PPME_SYSCALL_MKNODAT_E))
{
return 0;
}

ringbuf__store_event_header(&ringbuf);

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

// Here we have no parameters to collect.

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

ringbuf__submit_event(&ringbuf);

return 0;


}

/*=============================== ENTER EVENT ===========================*/

/*=============================== EXIT EVENT ===========================*/

SEC("tp_btf/sys_exit")
int BPF_PROG(mknodat_x,
struct pt_regs *regs,
long ret)
{
struct auxiliary_map *auxmap = auxmap__get();
if(!auxmap)
{
return 0;
}

auxmap__preload_event_header(auxmap, PPME_SYSCALL_MKNODAT_X);

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

/* Parameter 1: ret (type: PT_ERRNO) */
auxmap__store_s64_param(auxmap, ret);

/* Parameter 2: dirfd (type: PT_FD) */
s32 dirfd = (s32)extract__syscall_argument(regs, 0);
if(dirfd == AT_FDCWD)
{
dirfd = PPM_AT_FDCWD;
}
auxmap__store_s64_param(auxmap, (s64)dirfd);

/* Parameter 2: path (type: PT_CHARBUF) */
unsigned long path_pointer = extract__syscall_argument(regs, 1);
auxmap__store_charbuf_param(auxmap, path_pointer, MAX_PATH, USER);

/* Parameter 3: mode (type: PT_MODE) */
u32 mode = (u32)extract__syscall_argument(regs, 2);
auxmap__store_u32_param(auxmap, mknod_mode_to_scap(mode));

/* Parameter 4: dev (type: PT_UINT32) */
u32 dev = (u32)extract__syscall_argument(regs, 3);
auxmap__store_u32_param(auxmap, dev);


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

auxmap__finalize_event_header(auxmap);

auxmap__submit_event(auxmap, ctx);

return 0;
}

/*=============================== EXIT EVENT ===========================*/
16 changes: 15 additions & 1 deletion driver/ppm_events_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@ or GPL2.txt for full copies of the license.
#define PPM_S_ISGID (1 << 10)
#define PPM_S_ISUID (1 << 11)

/*
* mknod() modes
*/
#define PPM_S_IFREG 0100000
#define PPM_S_IFCHR 0020000
#define PPM_S_IFBLK 0060000
#define PPM_S_IFIFO 0010000
#define PPM_S_IFSOCK 0140000

/*
* flock() flags
*/
Expand Down Expand Up @@ -1394,7 +1403,11 @@ typedef enum {
PPME_SYSCALL_INIT_MODULE_X = 411,
PPME_SYSCALL_FINIT_MODULE_E = 412,
PPME_SYSCALL_FINIT_MODULE_X = 413,
PPM_EVENT_MAX = 414
PPME_SYSCALL_MKNOD_E = 414,
PPME_SYSCALL_MKNOD_X = 415,
PPME_SYSCALL_MKNODAT_E = 416,
PPME_SYSCALL_MKNODAT_X = 417,
PPM_EVENT_MAX = 418
} ppm_event_code;
/*@}*/

Expand Down Expand Up @@ -2090,6 +2103,7 @@ extern const struct ppm_name_value pf_flags[];
extern const struct ppm_name_value unlinkat_flags[];
extern const struct ppm_name_value linkat_flags[];
extern const struct ppm_name_value chmod_mode[];
extern const struct ppm_name_value mknod_mode[];
extern const struct ppm_name_value renameat2_flags[];
extern const struct ppm_name_value openat2_flags[];
extern const struct ppm_name_value execve_flags[];
Expand Down
Loading

0 comments on commit bd2d62c

Please sign in to comment.