Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(driver): support for mknod/mknodat syscall #1270

Merged
merged 2 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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, bpf_encode_dev(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, bpf_encode_dev(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_FSPATH, 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_USES_FD, 5, {{"res", PT_ERRNO, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"path", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)},{"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, encode_dev(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, encode_dev(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
Loading